在处理目标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] ;
}
然后在dealloc中释放_success和_fail
并在@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);
}
我希望这可以更深入地了解我做错了什么。
编辑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)。
答案 0 :(得分:1)
内存管理并没有什么不同,因为您使用的是异步回调。 myArchive
应该是你正在做的任何课程的属性。你希望它一直存在,直到任务完成,对吗?
@property (retain) MyClass *myArchive;
然后..
myArchive = [[MyClass alloc] init];
void (^on_success_callback)(void) = ^(void){
NSLog(@"success");
self.myArchive = nil;
};
您需要确保正确管理回调,即从堆栈中复制它们并在完成后释放它们。
如果您的代码中有保留和发布,则可能没有正确使用访问方法。