Objective 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をいつどのようにリリースするかがわからないことです。内のInstrumentsを使用し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];
}
実際のメモリリークは、コールバックが何らかの理由で失敗をキャッチし、コールバック内から[selfretrieveGallery]関数を呼び出して再試行する場合のみです。これがリークの原因になっているので、それは大したことではないと思います。関数(この場合はretrieveGallery)を再試行するにはどうすればよいですか。