2012-02-06 44 views
0

我的代码存在问题,对于我来说我无法弄清楚,甚至没有以前的所有线程。 我从JSON源拉取数据并将其放入NSDictionary中,如教程和SO中所述。在分析应用程序时,我注意到由此NSDictionary引起的内存泄漏,但在此函数结束时释放它会使应用程序崩溃。有什么建议么? (顺便说一句:我是新来的,一般的OBJ-C和编程,所以这段代码主要是从各种来源cherrypicked。)NSDictionary泄漏内存

- (void)fetchedData:(NSData *)responseData { 
    //parse JSON for empty return 
    if([responseData length] != 0){ 

     NSError* error = nil; 
     //Convert JSON data to Obj-C 
     NSDictionary* allShotData = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error]; 

     NSString *player = [[allShotData objectForKey:@"player"] objectForKey:@"name"]; 
     NSString *shotDribbblePage = [allShotData objectForKey:@"url"]; 

     NSString *shotTitle = [allShotData objectForKey:@"title"]; 
     NSURL *imageURL = [NSURL URLWithString:[allShotData objectForKey:@"image_url"]]; 
     shotPageURL = [shotDribbblePage retain]; 


     //*********************** 
     // Setup a-sync loading of shot 
     //*********************** 

     NSOperationQueue *queue = [NSOperationQueue new]; 
     NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadImage:) object:imageURL]; 
     [queue addOperation:operation]; 
     [operation release]; 
     [queue release]; 
    } 
    else{ 
     airballCount++; 
     if (airballCount <= 20) { 
      [self getDribbbleData]; 
     } 
     else{ 
      NSLog(@"Too many airballs. Bailing out"); 
      [self showNoConnectionModal]; 
     } 
    } 
} 

回答

2

这里:

shotPageURL = [shotDribbblePage retain]; 

你应该使用访问者:

self.shotPageURL = shotDribbblePage; 

我应该真的强调,因为他们做你的裁判计数FO你应该用你的访问器无处不在你(例外:不在初始化程序和dealloc中)。正如铍所指出的那样,如果没有访问器,你可以手动进行参考计数。这需要基本形式:

[shotPageURL release]; 
shotPageURL = [shotDribbblePage retain]; 

如果它有泄漏返回字典的内容,那么它的时候(过保留)读你如何应用/引用的内容。

如果你在并发上下文中使用你的类,那么你通常需要一个锁。

如果您正在加载UIImage或以其他方式与来自辅助线程的UIKit对象进行交互 - 这不太好。

+1

或'[shotPageURL发布]; shotPageURL = nil; shotPageURL = [shotDribbblePage retain];'如果没有属性。 – beryllium 2012-02-06 09:27:46

+0

@beryllium指出 - 谢谢。 – justin 2012-02-06 09:34:02

+0

谢谢贾斯汀,这确实是问题之一,但事实证明这不是唯一的问题。一个人提到复制shotDribbblePage添加副本,然后手动释放它。这显然是因为红色的秒杀不再出现。 – 2012-02-06 09:52:06