从后台线程访问实例变量

时间:2012-06-30 20:34:25

标签: iphone objective-c ios multithreading

假设我有一个已分配和初始化的实例变量MyObject。然后说我这样做:

[backgroundThread performBlock:^{
    //do something with MyObject that might take some time
}];

[self dismissModalViewController]; //this releases all instance variables, right?

所以会发生什么呢?我有一个名为NSManagedObjectContext的{​​{1}},可以在后台处理某个对象。这会立即返回并在后台完成工作,然后调用backgroundThread,它会释放所有实例变量。那么如果模态视图现在被解除了,但dismissModalViewController仍然需要使用该对象呢?这是一个问题吗?解决方法是什么?

另一件事:将此MyObject插入到托管对象上下文backgroundThread中。这是否意味着即使在解除视图后,此NSManagedObjectContext仍将保留该对象?

我正在使用ARC。

2 个答案:

答案 0 :(得分:5)

在这里你需要考虑几件事。首先请记住,块将捕获它所指的任何内容。因此,您可能不需要执行任何特殊操作,并且您的代码可以正常工作,具体取决于您在块中正在执行的操作。 Apple的Block Programming Topics文档中描述了块捕获的规则,以及如何处理每个变量取决于其类型。特别是,

  

在手动引用计数环境中,复制块时会保留块中使用的局部变量。在块中使用实例变量将导致保留对象本身。如果您希望覆盖特定对象变量的此行为,可以使用__block存储类型修饰符对其进行标记。

     

如果您使用ARC,则会在复制块并稍后释放时自动保留和释放对象变量。

要考虑的另一件事是访问实例变量可能是也可能不是线程安全的。通过声明为atomic的属性访问实例变量是朝着正确方向迈出的一步,但您可能需要使用互斥锁或其他技术来根据具体情况同步访问。

答案 1 :(得分:1)

如果要引用(模态)视图控制器的ivars或其他属性,则需要确保模态视图控制器仍然存在。

以下是来自Apple's documentation on dismissModalViewControllerAnimated:的潜在有用提示:

  

如果您想保留对接收者呈现视图的引用   controller,之前获取modalViewController属性中的值   调用这种方法。

可能有用的另一个想法是创建&实例化一个单独的对象,该对象封装您要从视图控制器或任何其他线程访问的数据/对象。