3

我的主要程序产生一个线程,它执行以下操作:Objective-C的NSThread裁判计数约定(保留VS自动释放)

// alloc autorelease pool somewhere before 
NSArray *blah = [NSArray arrayWithObject: @"moo"]; 
[self performSelectorOnMainThread: @selector(boonk:) withObject: blah 
     waitUntilDone: NO]; 
// release autorelease pool somewhere after 

现在,这似乎是车对我来说,因为自动释放池会前发布选择器boonk:完成执行,这会导致崩溃。

所以,我自然的下一步行动将是:

// alloc autorelease pool somewhere before 
NSArray *blah = [[NSArray alloc] initWithObject: @"moo"]; 
[self performSelectorOnMainThread: @selector(boonk:) withObject: blah 
     waitUntilDone: NO]; 
// release autorelease pool somewhere after 


- (void)boonk: (id)data 
{ 
    // do something with data 
    [data release]; // release the ref count the thread added 
} 

这绝对是无bug,但似乎....不自然。是否有一个Objective-c计数约定或协议来处理这种情况(跨线程无等待发布),还是第二个解决方案超出了它的做法?

回答

9

实际上,performSelectorOnMainThread保留其参数直到之后执行选择器,因此不需要这样做。

+0

那么,我会加快,就是这样。他们在方法描述结束时将其隐藏在一个小小的便笺中。太棒了,谢谢! – MarcWan 2010-01-11 11:13:46

+0

嗯,我只记得*直到选择器被执行*,而不是*之后* :) – 2010-01-11 11:15:52

+0

嗯,在执行选择器之后不会释放参数(NSArray等等)吗?框架保留论点的全部目的是让你免于保留和释放它,并确保你不会忘记保留它导致崩溃。自动释放池在这里超出范围,因为编码器不保留参数,但是框架在必要时保留并释放它。 – Costique 2010-01-11 11:19:54

3

规则很简单;要将线程A中的对象传递给线程B,必须存在硬保留。现在,如记录,-performSelectorOnMainThread:(和变体)保留的对象,直到方法完成执行,无论同步或异步调用。

但是,通常是保持发送线程保留发送线程的主题。这是明确的意图,并将支持未来的重构,潜在的其他模型,而不是做自动保留/释放。

而且,要重复一次,因为它很重要,autorelease池不能用于跨线程保留对象。