可可的NSArray/NSSet中:-makeObjectsPerformSelector:对快速列举
我想通过存储在NSSet
几个对象执行相同的操作。可可的NSArray/NSSet中:-makeObjectsPerformSelector:对快速列举
我第一次尝试使用一个快速列举:
for (id item in mySetOfObjects)
[item action];
它工作得很好。然后我想到:
[mySetOfObjects makeObjectsPerformSelector:@selector(action)];
而现在,我不知道什么是最好的选择。据我所知,这两种解决方案是等价的。但是有没有更喜欢一种解决方案的论点?
我认为使用makeObjectsPerformSelector
,因为它允许的NSSet对象照顾自己的索引,循环和消息收发。编写NSSet代码的人最有可能知道实现该特定循环的最佳方式。
在最坏的情况下,他们只会实现完全相同的循环,而您获得的所有代码都是稍微更干净的代码(不需要包含循环)。充其量,他们做了一些内部优化,代码实际上运行得更快。
的主题简要苹果Code Speed Performance文件标题为“展开循环”一节中提到。
如果您关心性能,最好的办法是设置一个快速程序,对一组中的对象执行一些选择器。让它运行数百万次,并且计算两种不同情况之间的差异。
makeObjectsPerformSelector:
可能稍微快一点,但我怀疑有将是时间的任何实际差别99%。虽然它更简洁明了,但我会因为这个原因而使用它。
我不会用makeObjectsPerformSelector,原因很简单,它是一种叫,你没有看到所有的时候。这就是为什么例如 - 我需要添加调试代码作为枚举数组,而你真的不能使用makeObjectsPerformSelector来做到这一点,除非你改变代码如何在Release模式下工作,这是一个真正的否定。
for (id item in mySetOfObjects)
{
#if MY_DEBUG_BUILD
if ([item isAllMessedUp])
NSLog(@"we found that wily bug that has been haunting us");
#endif
[item action];
}
--Tom
我也提交了这个问题。我发现在苹果的文档“类别编程主题”,“Sets: Unordered Collections of Objects”下的以下内容:
的NSSet中的方法objectEnumerator让 您遍历集合中的一个 接一个的元素。而 themakeObjectsPerformSelector:和 makeObjectsPerformSelector:withObject: 方法提供了在一组发送消息 单个对象。在 大多数情况下,快速枚举应该使用 ,因为它比使用NSEnumerator或 makeObjectsPerformSelector: 方法更灵活,更灵活 。有关枚举的更多信息,请参见 “枚举:遍历一个 集合的元素。“
这使我相信快速枚举仍然是此应用程序的最有效手段。
如果纯粹的速度是唯一的问题(即你正在创建一个渲染引擎,每个微小的CPU周期计数),迭代通过任何NSCollection对象(从iOS 5.0到6.0)的最快方法是各种“enumerateObjectsUsingBlock”方法。我不知道这是为什么,但我测试了它,这似乎是这样的...
我写了小测试创建数以十万计的对象的集合,每个对象都有一个方法,它将一个简单的int数组。这些集合中的每一个都被迫执行各种类型的迭代(for循环,快速枚举,makeObjectsPerformSelector和enumerateObjectsUsingBlock)数百万次,并且在几乎所有情况下,“enumerateObjectsUsingBlock”方法都在测试过程中轻松胜出。
唯一不是这样的情况是,当内存开始填满时(我开始用对象的百万运行它),之后它开始失去“makeObjectsPerformSelector”。
对不起,我没有拍摄代码的快照,但这是一个非常简单的测试,我强烈建议您尝试一下,看看自己。 :)
谢谢你的链接,我不知道这个文件!正如你所说,“展开循环”一节明确指出Cocoa开发者已经用-makeObjectsPerformSelector: – mouviciel 2009-02-24 19:53:11