我在我的应用程序中使用以下模式并且正在过渡到 ARC。基本上,对象保留 Controller 的一个实例,并在通过委托(delegate)协议(protocol)通知它已完成时释放该 Controller 。我不使用 iVar/property b/c startProcess 可以调用 N 次来处理 N 件事。

下面的例子:

// start a process in a controller
- (void)startProcess
{
    MyController *controller = [[MyController alloc] init];
    // set the delegate, the delegate is defined as (nonatomic, assign)
    controller.delegate = self;
    [controller start];
}

// when the delegate is notified, release the controller
- (void)myControllerDidFinish:(MyController):controller
{
    // do something with results
    [controller release];
}

当上述实现转换为 ARC 时,startProcess 结束后不再保留 Controller ,因此不会发生处理并且永远不会收到委托(delegate)消息。

问题:将我的项目转换为使用 ARC 时,如何将上述实现修改为正常工作,而无需在实例化 Controller 的对象中创建 iVar?在 Apple 的文档中有一个类似的例子来过渡到 ARC,但它涉及使用块。我宁愿不用完成块替换委托(delegate)协议(protocol)。

编辑:在代码中添加了关于如何定义委托(delegate)的注释

编辑:澄清第一段以解释为什么持有 Controller 的 iVar/属性不起作用

最佳答案

通常,控制者有责任在完成任务时保留自己。如果您的 Controller 在后台线程上运行任务,那么它应该自动由 NSThread 的实例保留。如果使用 NSURLConnection 通过网络获取数据,则 Controller 应保留为 delegate

如果您没有执行这样的任务,则可以在执行任务时使用合成循环保留来保留 Controller 。这可以通过创建一个对象来完成,我称之为 ObjectRetainer ,它只有一个 __strong id 属性。当 Controller 开始其任务时,它应该有一个 __strong ObjectRetainer 实例变量,该变量被设置为保留 Controller 的新 ObjectRetainer。这样, Controller 会保留一个 ObjectRetainer 来保留 Controller ,从而防止任何一个被释放。

当 Controller 完成其任务并调用了所有必要的委托(delegate)方法时,它应该将 ObjectRetainer 实例变量设置为 nil。这将释放 ObjectRetainer ,进而释放 Controller 。
ObjectRetainer 接口(interface)可能如下所示:

@interface ObjectRetainer : NSObject {
    __strong id object;
}
@property (nonatomic, strong) __strong id object;
@end

您应该在 Controller 的头文件中声明一个 ivar: __strong ObjectRetainer _retainer 。然后,在 Controller 的 start 方法中:
- (void)start {
    ...
    _retainer = [[ObjectRetainer alloc] init];
    _retainer.object = self;
}

Controller 完成后,只需将 _retainer 设置为 nil:
- (void)performBackgroundTask {
    ....
    [delegate myControllerDidFinish:self];
    _retainer = nil;
}

关于objective-c - 在转换为 ARC 时,如何确保 Controller 在完成处理之前一直保留?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7869073/

10-11 22:25
查看更多