【问题标题】:iOS release not working as expectediOS 版本未按预期工作
【发布时间】:2012-08-24 11:04:21
【问题描述】:

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

【问题讨论】:

  • 如果他使用ARC,编译器会抱怨release

标签: ios memory memory-management memory-leaks


【解决方案1】:

你需要正确分配你的数组:

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

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

【讨论】:

    【解决方案2】:

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

    无论哪种方式,我都认为问题不在于 [release],而可能是 BEFORE release:

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

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        我发现似乎是解决该问题的更好方法。这让 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];
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-20
          • 1970-01-01
          • 2022-01-03
          • 1970-01-01
          • 2016-09-07
          相关资源
          最近更新 更多