从 Documents 目录存储和读取文件 iOS 5文件、目录、Documents、iOS

2023-09-06 09:59:19 作者:半世浮生

在我的游戏中,当一个关卡完成时,应用程序会在应用程序的 Documents 目录中的文件中存储一个1".当游戏加载时,玩家只有在上一个关卡已经完成的情况下才能玩一个关卡.当我通过 Xcode 在设备上测试游戏时,应用程序可以正常工作,并且在完成上一个关卡之前无法玩关卡.但是,当应用程序获得批准并在 App Store 上发布时,应用程序的行为就像每个级别都已完成(没有锁定级别).我无法弄清楚这一点,并希望有人的帮助!我正在测试的设备都是 iO 5.0 或更高版本.

In my game, when a level is completed the app stores a "1" in a file in the Documents directory of the app. When the game then loads, a player can only play a level if the previous level has been completed. When I test the game via Xcode and on a device the app works properly and a level cannot be played until the previous level has been completed. However, when the app was approved and released on the App Store, the app behaves as if each level has been completed (no locked levels). I can't figure this one out and would appreciate someone's help! The devices I'm testing on are all iOs 5.0 or higher.

以下是将完成的关卡保存在 Documents 目录中的代码:

Below is the code that saves the completed level in the Documents directory:

 NSMutableData* data = [[NSMutableData alloc] init];
        NSKeyedArchiver* coder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
        NSString *levelString = [NSString stringWithFormat:@"Level%d",level];
        [coder encodeInteger:1 forKey:levelString];
        [coder finishEncoding];
        NSString *levelString2 = [NSString stringWithFormat:@"Level%d.save",level];
        ///
        NSFileManager *filemgr;
        NSString *dataFile;
        NSString *docsDir;
        NSArray *dirPaths;

        filemgr = [NSFileManager defaultManager];

        // Identify the documents directory
        dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

        docsDir = [dirPaths objectAtIndex:0];

        // Build the path to the data file
        dataFile = [docsDir stringByAppendingPathComponent:levelString2];

        // Check if the file already exists
        if ([filemgr fileExistsAtPath: dataFile])
        {
            [[NSFileManager defaultManager] removeItemAtPath:dataFile error:nil];
        }
        [data writeToFile:dataFile atomically:YES];
        [coder release];
        [data release];
    }
    @catch (NSException* ex) 
    {
        CCLOG(@"level save failed: %@", ex);
    }

下面是读取Document目录看关卡是否完成的代码:

Below is the code that reads the Document directory to see if the level has been completed:

if ([self loadCompletedLevels:6] == 1) { //// level gets unlocked **** }

-(int) loadCompletedLevels:(int)theLevel; {

int isLevelCompleted;  //1 = completed

NSString* kSaveFile = [NSString stringWithFormat:@"Level%d.save",theLevel];
NSString *levelString = [NSString stringWithFormat:@"Level%d",theLevel];

@try
{

    NSFileManager *filemgr;
    NSString *dataFile;
    NSString *docsDir;
    NSArray *dirPaths;

    filemgr = [NSFileManager defaultManager];

    // Identify the documents directory
    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    docsDir = [dirPaths objectAtIndex:0];

    // Build the path to the data file
    dataFile = [docsDir stringByAppendingPathComponent:kSaveFile];


    if ([[NSFileManager defaultManager] fileExistsAtPath:dataFile])
    {
        NSData* data = [[NSData alloc] initWithContentsOfFile:dataFile];

        if (data && [data length] > 0)
        {
            NSKeyedUnarchiver* decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
            isLevelCompleted = [decoder decodeIntForKey:levelString];

            [decoder release];
        }

        [data release];
    }
    if (isLevelCompleted == 1) {
        levelCompleted = YES;

    }
}
@catch (NSException* ex) 
{

    levelCompleted = NO;
}
return isLevelCompleted; }

推荐答案

您可能应该使用不同的方法来存储数据,但真正的问题是您没有初始化返回值 isLevelCompleted.它在堆栈上,没有默认值.它从堆栈位置发生的任何事情开始.

You should probably use a different approach for storing your data, but the real problem is that you are not initializing the return value, isLevelCompleted. It is on the stack, and does not have a default value. It starts out with whatever happens to be at that stack location.

所以,如果你不设置它,它将有一个任意值.

So, if you don't set it, it will have an arbitrary value.

此外,您可能应该使用 BOOL 作为布尔值,但如果您这样做:

Also, you should probably use BOOL for a boolean value, but if you make this:

int isLevelCompleted = 0;  //1 = completed

您会将其初始化为false",因此您的代码必须将其显式更改为true".

you will initialize it to "false" so it must be explicitly changed to "true" by your code.