以下过程会导致我的应用崩溃:
并执行以下代码
// MyDatasource.m
// e.g. in connectionDidFinishLoading
[callback loadedDataSource:self];
与此同时,其他模型/视图已被解除分配,并且消息将被发送到解除分配的实例。
callback
的类型为id
,符合KalDataSourceCallbacks
协议。
如何避免将消息发送到解除分配的对象?
PS:我的问题类似于this question
修改
我将尝试在callback
方法(在我的数据源类中)中将dealloc
设置为nil。这并不能解决问题,因为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:
我可以查看callback
nil
以查看它是否已被释放?
if (callback != nil)
[callback loadedDataSource:self];
这没有帮助。
编辑3:
应用程序没有崩溃,因为我保留了委托:
@property (retain) id<KalDataSourceCallbacks> callback;
应该是
@property (assign) id<KalDataSourceCallbacks> callback;
那么我怎么能避免将方法loadedDataSource
发送到我的特殊情况的解除分配对象?
答案 0 :(得分:1)
当您离开当前视图时,将委托设置为nil。
答案 1 :(得分:0)
您需要确保完成连接并将其释放并将其设置为nil。 发送到nil对象的消息将被忽略。
答案 2 :(得分:0)
在KalDataSource.h
中,我将以下方法添加到KalDataSource
协议:
@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;
}
并将委托设置为nil。