2010-10-29 18 views
0

以下過程導致我的應用程序崩潰:如何避免回調發送到釋放實例

  • 用戶打開視圖和請求被髮送到
  • 執行請求的服務器在背景
  • 用戶導航回到根視圖
  • 請求已經完成

和以下共同德執行

// MyDatasource.m 
// e.g. in connectionDidFinishLoading 
[callback loadedDataSource:self]; 

在其他模型/視圖已釋放的同時,消息被髮送到一個釋放的實例。

callbackid類型,並符合KalDataSourceCallbacks protocoll。

如何避免消息發送到釋放對象?

PS:我的問題是類似this question

編輯:

我會嘗試設置callback爲零的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; 
    // ... 
} 

目前該應用程序不會崩潰。我必須在設備上進行測試。添加callback = nil在這裏沒有做任何事情,因爲dealloc永遠不會被調用。

日曆銷燬後應如何釋放MyDataSource?這不起作用,因爲我不知道日曆是否已被銷燬。所以dataSource只能存在於整個應用程序運行時。

編輯2:

我可以檢查callbacknil,以找出是否已經釋放?

if (callback != nil) 
    [callback loadedDataSource:self]; 

這沒有幫助。

編輯3:

該應用程序並沒有崩潰,因爲我保留了委託:

@property (retain) id<KalDataSourceCallbacks> callback; 

應該

@property (assign) id<KalDataSourceCallbacks> callback; 

所以,我怎麼能避免這種情況的方法loadedDataSource是發送給我的特例的釋放對象?

回答

0

KalDataSource.h我添加下面的方法到KalDataSource protocoll:

@protocol KalDataSource <NSObject, UITableViewDataSource> 
    // ... 
    - (void)destroyCallback; 
@end 

KalDataSource.m我添加的方法擺脫了警告:

@implementation SimpleKalDataSource 
// ... 
- (void)destroyCallback 
{ 
    // do nothing 
} 
@end 

KalViewController.m我打電話給我的之前創建的方法時,對象被釋放:

- (void)dealloc 
{ 
    // ... 
    [dataSource destroyCallback]; 
} 

MyDataSource.m我執行的功能

- (void)destroyCallback { 
    self.callback = nil; 
} 

,並委託設爲零。

1

當您移出當前視圖時,將委託設置爲nil。

+0

委託在'MyDataSource'類中。 – testing 2010-10-29 14:31:09

+0

您可以以@property的身份訪問它。仍然不確定這是否是首選的方式。 – fabb 2011-08-24 09:11:50

0

您需要確保完成連接並釋放連接並將其設置爲零。 發送給零對象的消息被忽略。

+0

連接可以完成,因爲我的數據源類是在'RootViewController'中創建的,因此始終可用。 (我還沒有找到用於整合Kal日曆的另一個解決方案)。因此,釋放「RootViewController」時會完成數據源類的發佈。 – testing 2010-10-29 13:04:09

+0

一種可能性是在'KalViewController'的'dealloc'方法中將委託設置爲'nil'。這可以通過發送消息或通知中心的幫助來實現。但是,我不得不修改'KalViewController',這不是最好的解決方案。詳細地說,如果我想升級到更新的版本,則每次修改都必須重新進行(可能不是我的人)。但這是獲得這項工作的最後一個可能性。 – testing 2010-10-29 14:36:20

+0

您還需要了解保留週期。要麼我採取弱參考或使用觀察者模式... – testing 2010-10-29 16:33:20

相關問題