2011-09-14 63 views
4

我在处理目标c中的回调和异步代码时遇到了内存管理问题。 我似乎找不到一种方法来释放回调设置的实例。使用回调时的内存泄漏

例如:

MyClass *myArchive = [[MyClass alloc] init] ; 
[myArchive callBack:^(RKObjectLoader* objectLoader, id object) { 

    NSLog(@"success"); 

} fail:^(RKObjectLoader* objectLoader, NSError* error) { 

    NSLog(@"failed"); 


}]; 

[myArchive searchArchive:words:paging]; 

的问题是,我不知道何时或如何释放实例* myArchive。使用xcode中的工具来分析我的代码,我总是会在这里发现泄漏。函数searchArchive使用restkit向服务器执行异步请求。我不会从回调中引用实例,因为我听说这会导致保留周期,并且我已经做了一些关于使用__block和其他c方法的阅读,以避免保留周期,这一切都很好,但现在没有实际的代码发生在回调如何释放* myArchive实例。任何人都能解释我应该如何在objective-c内处理这个问题?

编辑:

这是我在MyClass的

// Sets internal backs on this object which basically wrap the delegate 
// 
- (void)callBack: (void (^)(RKObjectLoader* objectLoader, id object))success 
      fail: (void (^)(RKObjectLoader* objectLoader, NSError* error))fail { 
    //sanity check 
    NSAssert(_currentDelegate != self, @"Delegate is another object. Can not set callback"); 

    // store our callback blocks in the instance 

    _success = [success copy] ; 
    _fail = [fail copy] ; 
} 

设置回调,然后释放_success和_fail中的dealloc

和@interface

@interface myClass : NSObject<RKObjectLoaderDelegate> { 
    // holds the block callback for "success" 
    void (^_success)(RKObjectLoader* objectLoader, id object); 
    // holds the block callback for "fail" 
    void (^_fail)(RKObjectLoader* objectLoader, NSError* error); 
} 

我希望这给我更多的见解我nto我做错了什么。

编辑2:

好吧,我开始看到现在的错误:

-(void)retrieveGallery{  

    //create call back for async and deal with the result 
    [_galleryItems callBack:^(RKObjectLoader* objectLoader, NSArray *objects) { 

     //success happy days. do a bunch of code here that does not cause leaks 

    } fail:^(RKObjectLoader* objectLoader, NSError* error) { 
     //retry the attempt to retrieve gallery data from the server 
     _retryCount++; 
     if (_retryCount < _maxRetryCount) { 
      [self retrieveGallery]; 
     } 


    }]; 

    //read the collection of gallery items from server 
    [_galleryItems readGallery]; 

} 

的唯一实际的内存泄漏是回调时抓住一个失败什么都原因,然后调用从回调中的[self retrieveGallery]功能再次尝试。这是什么导致泄漏,所以我猜这是一个很大的不是。我应该如何再次尝试函数(在这种情况下为retrieveGallery)。

回答

1

因为您正在使用异步回调,所以内存管理并没有什么不同。 myArchive应该是您正在执行此操作的任何课程的属性。您希望它坚持到任务完成为止,对吗?

@property (retain) MyClass *myArchive; 

然后..

myArchive = [[MyClass alloc] init]; 

void (^on_success_callback)(void) = ^(void){ 
    NSLog(@"success"); 
    self.myArchive = nil; 
}; 

你需要确保你合理管理的回调,即从堆栈中复制它们并释放他们时,你就完成了。

如果你有保留的,你可能没有使用存取方法正确地在你的代码版本。

+0

我可能是爱上你了,现在 – glogic

+0

偶然的这项工作的结果,并可能导致过早释放'myArchive'。简单地改变'@ property'的atomocity会导致'myArchive'去分配,同时在后台线程上测试时仍然调用回调函数。 – Joe

+0

是的,经过进一步的测试后,出现了同样的问题。回到解决这个问题的绘图板上。将尝试更多的东西,明天再回到这个主题。在这里迟到 – glogic