XCode崩溃日志NSMutableDictionary无检查问题

时间:2012-02-08 00:23:08

标签: iphone objective-c xcode cocoa-touch

我的Xcode崩溃日志指向崩溃的这行代码:

if(contentDict != nil && [contentDict count] > 0) {

我原以为这不会崩溃,因为它首先检查'nil',并且'&&''它不会再检查。它能否在前一行失败?我有2个崩溃日志指向完全相同的行号。以下是它的方法:

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
channelIndex = [[NSMutableArray alloc] init];

BOOL reachable = [self networkReachable];
if (!reachable) {
    NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:kContent];       
    contentDict = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    if(contentDict == nil || [contentDict count] == 0) {
        contentDict = [[NSMutableDictionary alloc] init];
    }
    data = [[NSUserDefaults standardUserDefaults] objectForKey:kHistory];       
    historyDict = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    if(historyDict == nil || [historyDict count] == 0) {
        historyDict = [[NSMutableDictionary alloc] init];
    }
}

if(selectedIndex == 0) {
    if(contentDict != nil && [contentDict count] > 0) {
        NSArray *keys = [contentDict allKeys];
        keys = [keys sortedArrayUsingSelector: @selector (compare:)];  
        for (NSString *key in keys) {
            NSLog(@"%@ is %@",key, [contentDict objectForKey:key]);
            Content *content = [contentDict objectForKey:key];
            if (![channelIndex containsObject:content.channelName])
            {            
                [channelIndex addObject:content.channelName];
            }        
        }
    }
} else {
    if(historyDict != nil && [historyDict count] > 0) {
        NSArray *keys = [historyDict allKeys];
        keys = [keys sortedArrayUsingSelector: @selector (compare:)];  
        for (NSString *key in keys) {
            NSLog(@"%@ is %@",key, [historyDict objectForKey:key]);
            Content *content = [historyDict objectForKey:key];
            if (![channelIndex containsObject:content.channelName])
            {            
                [channelIndex addObject:content.channelName];
            }        
        }
    }
}
return [channelIndex count];

}

2 个答案:

答案 0 :(得分:0)

[NSKeyedUnarchiver unarchiveObjectWithData:data]返回一个自动释放的对象。可能这是你的问题。在使用之前尝试保留结果。如果变量指向包含垃圾的内存区域,则检查nil将无法帮助您,因为它已被自动释放。

答案 1 :(得分:0)

您提供的代码仅在网络无法访问时设置contentDict实例变量,因此第一个问题是:当网络 可达时,它是如何设置的?很有可能,它被设置在其他地方而没有被正确保留,因此在您进行检查之前,字典会被解除分配。

以下是一些建议:

  1. 使用下划线为您的实例变量添加前缀,例如: _contentDict而不是contentDict
  2. 避免直接引用init...dealloc和getter / setter对以外的方法中的实例变量。改为使用属性。
  3. 不要费心检查nil - 这里不相关(对nil的消息对所有非结构返回类型都返回零)。
  4. 确保您了解内存管理规则。如果您正在使用ARC进行编译:Advanced Memory Mangement Programming Guide;否则:Transitioning to ARC Release Notes