утечка памяти при использовании обратного вызова - PullRequest
4 голосов
/ 14 сентября 2011

У меня проблема с управлением памятью при работе с обратными вызовами и асинхронным кодом в задаче 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 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] из обратного вызова, чтобы попытаться снова.это то, что вызывает утечку, поэтому я предполагаю, что это большой нет, нет.Как я должен попытаться использовать функцию (в данном случае, получить галерею)?

1 Ответ

1 голос
/ 14 сентября 2011

Управление памятью на самом деле ничем не отличается, потому что вы используете асинхронный обратный вызов.myArchive должно быть свойством любого класса, в котором вы это делаете. Вы хотите, чтобы оно оставалось до завершения задания, верно?

@property (retain) MyClass *myArchive;

Тогда ..

myArchive = [[MyClass alloc] init];

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

Вы должны убедиться, что управляете обратными вызовами должным образом, то есть копируете их из стека и освобождаете их, когда закончите.

Если в вашем коде сохраняются и выпускаются данные, вы, вероятно, не используете средство доступаметоды правильно.

...