2011-09-14 65 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