次のプロセスにより、アプリがクラッシュします。
- ユーザーがビューを開き、リクエストがサーバーに送信されます
- リクエストはバックグラウンドで実行されます
- ユーザーはルートビューに戻ります
- リクエストは終了しました
そして、次のコードが実行されます
// MyDatasource.m
// e.g. in connectionDidFinishLoading
[callback loadedDataSource:self];
その間に、他のモデル/ビューの割り当てが解除され、メッセージが割り当て解除されたインスタンスに送信されます。
callbackタイプであり、プロトコルidに準拠しています。KalDataSourceCallbacks
メッセージが割り当て解除されたオブジェクトに送信されるのを回避するにはどうすればよいですか?
PS:私の質問はこの質問に似ています
編集:
メソッド(データソースクラス)でcallbacknilに設定してみます。deallocこれは問題を解決しません。これは、MyDataSource常に存在し、リリースされたdealloc場合にのみメソッドを呼び出す必要RootViewControllerがあるためです(アプリを閉じたときに何が起こるか)。
私がこれまでにしたこと:
今私の:MyDataSourceのプロパティによって保持されますRootViewController
// RootViewController.h
@property (retain) MyDataSource *dataSource;
// RootViewController.m
@synthesize dataSource;
// ...
self.dataSource = [[[MyDataSource alloc] init] autorelease];
kal.dataSource = dataSource;
- (void)dealloc {
[dataSource release];
// ...
}
KalViewControllerはそのデータソースを保持しません。カレンダーが破棄された後に解放できるように、dataSourceへの参照をインスタンス変数に格納することをお勧めします。
プロパティも作成しましたcallback:
// MyDataSource.h
@property (retain) id<KalDataSourceCallbacks> callback;
// MyDataSource.m
@synthesize callback;
// ...
- (void)presentingDatesFrom:(NSDate *)fromDate to:(NSDate *)toDate delegate:(id<KalDataSourceCallbacks>)delegate {
// ...
self.callback = delegate;
}
- (void)dealloc {
[callback release];
callback = nil;
// ...
}
現在、アプリはクラッシュしていません。デバイスでテストする必要があります。ここでは、deallocが呼び出されないため、追加callback = nilしても何も行われません。
MyDataSourceカレンダーが破棄された後、どのようにリリースすればよいですか?カレンダーが破壊されているかどうかわからないので、それは機能しません。したがって、dataSourceはアプリの実行時間全体にわたってのみ存続できます。
編集2:
リリースされているかどうかcallbackを確認できますか?nil
if (callback != nil)
[callback loadedDataSource:self];
これは役に立ちません。
編集3:
デリゲートを保持したため、アプリはクラッシュしませんでした。
@property (retain) id<KalDataSourceCallbacks> callback;
する必要があります
@property (assign) id<KalDataSourceCallbacks> callback;
loadedDataSourceでは、特別な場合にメソッドが割り当て解除されたオブジェクトに送信されるのを回避するにはどうすればよいでしょうか。