2012-06-30 31 views
3

假设我有一个实例变量MyObject,它已被分配和初始化。然后说我这样做:从后台线程访问实例变量

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

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

所以会发生什么是我有一个NSManagedObjectContext称为backgroundThread,做背景的对象上的一些工作。这将立即返回并在后台执行该工作,然后调用dismissModalViewController,该工作将释放所有实例变量。那么如果模态视图现在被解散了,但是backgroundThread仍然需要使用该对象呢?这是一个问题吗?什么是解决方法?

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

我正在使用ARC。

+0

如果你的互斥量锁定了这个东西,你就不必担心它。 – CodaFi

+0

什么是互斥锁? – Snowman

+0

互斥锁保证当MyObject在后台处理时,其他线程无法触及它,包括取消分配它。 – CodaFi

回答

5

在这里有几件事情需要考虑。首先请记住,该块将捕获它引用的任何内容。所以你可能不需要做任何特别的事情,你的代码也可以正常工作,具体取决于你在你的块中做什么。苹果的Block Programming Topics文档中描述了块捕获的规则,并且每个变量的处理方式取决于其类型。特别是,

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

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

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

+0

请注意原子访问是SLOW。 – CodaFi

+0

将属性声明为'atomic'实际上很少是正确方向上的一步。在大多数并发访问方案下,单独制作属性“atomic”本身并不能使线程安全。您仍然需要提供保护,例如,使用互斥锁。一旦你提供了互斥锁,你通常不需要该属性为“原子”,正如CodaFi所说的那样,它速度较慢。 [下面是关于这个具体问题再议一下 - 原子(http://stackoverflow.com/questions/588866/atomic-vs-nonatomic-properties) – Nate

+0

在哪里可以找到更多有关的实例变量是否是线程安全的细节或不?我正在使用ARC .. – Snowman

1

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

这里有一个潜在的有用的提示,从Apple's documentation on dismissModalViewControllerAnimated:

如果你想保留给接收方提出看法 控制器的引用, 之前得到的modalViewController属性的值调用此方法。

可能工作另一个想法是创建&实例化一个单独的对象,它封装了要在任一视图控制器,或者任何其他线程访问数据/对象。

+0

等待我不明白你的最后一点是什么意思..谁会拥有这个单独的对象? – Snowman

+0

我用我发现的其他信息(使用视图控制器的“modalViewController”属性)修改了我的答案,但如果您确实继续使用单独的对象,则视图控制器和后台线程都可以引用(在ARC或ARC之外应该没问题)。 –

+0

您是否熟悉Core Data?检查出我的edit..MyObject已被插入到一个NSManagedObjectContext ..这意味着即使视图已被解雇,上下文将保留该对象? – Snowman