iOS版本无法按预期工作

时间:2012-08-24 11:04:21

标签: ios memory memory-management memory-leaks

我正在使用此代码从config.plist文件中获取图书名称。但是我的内存管理存在问题。 '[dict release]'完全打破了应用程序并退出。

代码在删除'[dict release]'时有效,但据我所知,它会导致内存泄漏。

bnames是一个全局的NSMutableArray

我做错了什么?

- (NSString *)loadBookname: (NSInteger) bookToLoad {
    bookToLoad = [self bookOrder:bookToLoad];

    //---get the path to the property list file---
    plistFileNameConf = [[self documentsPath] stringByAppendingPathComponent:@"Config.plist"];

    //---if the property list file can be found---
    if ([[NSFileManager defaultManager] fileExistsAtPath:plistFileNameConf]) {
        //---load the content of the property list file into a NSDictionary object---
        dict = [[NSDictionary alloc] initWithContentsOfFile:plistFileNameConf];
        bnames = [dict valueForKey:@"BookNames"];
        [dict release];
    }
    else {
        //---load the property list from the Resources folder---
        NSString *pListPath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"];
        dict = [[NSDictionary alloc] initWithContentsOfFile:pListPath];
        bnames = [dict valueForKey:@"BookNames"];
        [dict release];
    }
    plistFileNameConf = nil;

    NSString *bookNameTemp;
    bookNameTemp = [bnames objectAtIndex:bookToLoad - 1];
    NSLog(@"bookName: %@", bookNameTemp);
    return bookNameTemp;
}

4 个答案:

答案 0 :(得分:3)

您需要正确分配数组:

bnames = [[NSArray alloc] initWithArray:[dict valueForKey:@"BookNames"]];

仔细检查你的dict是否返回正确的数据类型。

答案 1 :(得分:1)

分配NSDictionary的方式似乎没有任何问题(尽管您也可以使用[NSDictionary dictionaryWithContentsOfFile:]并节省自己不必担心发布。

无论哪种方式,我都会建议问题不在于[发布],但可能是在发布之前的行:

bnames = [dict valueForKey:@"BookNames"];

a)分配的位置。我没有在任何地方看到它的分配或声明? b)您期望回到什么类型的价值?

给它一个断点,确保你得到你期望的东西。

答案 2 :(得分:0)

如果dict不是强属,请将其设为一个。然后,在分配时使用self.dict(并保留发布)。

答案 3 :(得分:0)

我发现似乎是一个更好的解决方案。这可以让iOS管理内存。

//---finds the path to the application's Documents directory---
- (NSString *) documentsPath {
    NSLog(@"Start documentsPath");
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [paths objectAtIndex:0];
    //  NSLog(@"Found documentsPath 40");
    NSLog(@"End documentsPath");
    return documentsDir;
}

- (NSString *) configPath {
    NSLog(@"Start configPath");
    NSString *plistFileNameConf = [[self documentsPath] stringByAppendingPathComponent:@"Config.plist"];
    if (![[NSFileManager defaultManager] fileExistsAtPath:plistFileNameConf]) {
        plistFileNameConf = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"];
    }
    NSLog(@"plistFile: %@",plistFileNameConf);
    NSLog(@"End configPath");
    return plistFileNameConf;
}

以下内容根据需要调用上述代码:

NSString *Choice;
NSArray *properties;
NSString *errorDesc = nil;
NSPropertyListFormat format;
NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:[self configPath]];
NSDictionary *temp = (NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
if (!temp) {
    NSLog(@"Error reading plist: %@, format: %d", errorDesc, format);
}
Choice = [temp objectForKey:@"Choice"];
properties = [temp objectForKey:Choice];