0

以下过程导致我的应用程序崩溃:

  • 用户打开视图并向服务器发送请求
  • 请求在后台执行
  • 用户导航回根视图
  • 请求已完成

并执行以下代码

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

与此同时,其他模型/视图已被解除分配,消息被发送到解除分配的实例。

callback是类型id并且符合KalDataSourceCallbacks协议。

如何避免将消息发送到已释放的对象?

PS:我的问题类似于这个问题

编辑:

我将尝试callback在方法中设置为零dealloc(在我的数据源类中)。这并不能解决问题,因为MyDataSource它始终存在,并且只有在释放dealloc时才应调用该方法RootViewController(关闭应用程序时应该发生什么)。

到目前为止我所做的:

现在MyDataSource由 my 中的一个属性保留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日历销毁后如何释放?这不起作用,因为我不知道日历是否已被破坏。所以数据源只能存在于整个应用程序运行时。

编辑2:

我可以检查callbacknil了解它是否已发布?

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

这没有帮助。

编辑3:

该应用程序没有崩溃,因为我保留了委托:

@property (retain) id<KalDataSourceCallbacks> callback;

应该

@property (assign) id<KalDataSourceCallbacks> callback;

那么,对于我的特殊情况,如何避免将该方法loadedDataSource发送到已释放的对象呢?

4

3 回答 3

1

当您移出当前视图时,将委托设置为 nil。

于 2010-10-29T12:39:05.433 回答
0

You will need to make sure that you finish the connection and release it and set it to nil. A message sent to a nil object is ignored.

于 2010-10-29T12:46:49.267 回答
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;
}

并将委托设置为零。

于 2010-10-29T18:02:02.607 回答