如何在转换为ARC后完成处理之前确保控制器保留?

XJo*_*nes 4 objective-c ios xcode4.2 automatic-ref-counting

我在我的应用程序中使用以下模式并转换到ARC.基本上,对象保留控制器的实例,并在通过委托协议通知它已完成时释放该控制器.我不使用iVar /属性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];
}
Run Code Online (Sandbox Code Playgroud)

当上述实现转换为ARC时,在startProcess结束后不再保留控制器,因此不会发生处理并且永远不会收到委托消息.

问题:在将我的项目转换为使用ARC时,如何修改上述实现以便在实例化控制器的对象中创建iVar而无法正常工作?Apple的文档中有一个类似的例子可以转换到ARC,但它涉及使用块.我宁愿不用完成块替换委托协议.

编辑:在代码中添加注释re如何定义委托

编辑:澄清第一段解释为什么持有控制器的iVar/property不起作用

Jef*_*ley 6

为什么不创建一个NSMutableArray实例变量pendingControllers,并在那里添加控制器?由于数组保留其成员,因此您的代码将如下所示:

// 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];

    if (pendingControllers == nil) {
        pendingControllers = [[NSMutableArray alloc] init];
    }
    [pendingControllers addObject:controller];
    [controller release];
}

// when the delegate is notified, release the controller
- (void)myControllerDidFinish:(MyController):controller
{
    // do something with results
    [pendingControllers removeObject:controller];
    if ([pendingControllers count] == 0) {
        // if ARC is enabled, remove the call to -release.
        [pendingControllers release], pendingControllers = nil;
    }
}
Run Code Online (Sandbox Code Playgroud)

这避免了这个问题.完成块正确的答案,它们是Apple正在使用的,但这种方法现在可以使用.