0

我正在使用此代码从 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

4 回答 4

3

您需要正确分配数组:

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

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

于 2012-08-24T11:15:04.963 回答
1

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

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

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

a) 分配在哪里。我在任何地方都看不到它的分配或声明?b) 您期望返回什么类型的价值?

在它上面设置一个断点,并确保你得到你所期望的或任何东西。

于 2012-08-24T11:33:56.077 回答
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];
于 2012-08-30T14:11:44.967 回答
0

如果dict它还不是一个强大的属性,那就让它成为一个。然后,self.dict在分配给它时使用(并保留释放)。

于 2012-08-24T11:14:57.903 回答