Mik*_*lah 16 cocoa multithreading core-data foundation nsindexpath
Apple的多线程文档不会NSIndexPath列为线程安全与否!作为一个不可变类,我通常认为它是线程安全的.
以前,我确信用于说明NSIndexPath实例已共享且全局唯一的文档.现在似乎已经消失了,让我怀疑iOS5/Mac OS X 10.7的设计已经修改.
我在Mac OS X 10.6(Snow Leopard)上看到了很多来自客户的崩溃报告,这些报告似乎在试图访问索引路径时崩溃.因此我想知道:实际的实例是线程安全的,但是将它们从共享缓存中拉出来的逻辑不是吗?有人有任何见解吗?
这是一个示例堆栈跟踪BTW:
Dispatch queue: com.apple.root.default-priority
0 libobjc.A.dylib 0x96513f29 _cache_getImp + 9
1 libobjc.A.dylib 0x965158f0 class_respondsToSelector + 59
2 com.apple.CoreFoundation 0x948bcb49 ___forwarding___ + 761
3 com.apple.CoreFoundation 0x948bc7d2 _CF_forwarding_prep_0 + 50
4 com.apple.Foundation 0x994b10c5 -[NSIndexPath compare:] + 93
5 com.apple.Foundation 0x99415686 _NSCompareObject + 76
6 com.apple.CoreFoundation 0x948af61c __CFSimpleMergeSort + 236
7 com.apple.CoreFoundation 0x948af576 __CFSimpleMergeSort + 70
8 com.apple.CoreFoundation 0x948af38c CFSortIndexes + 252
9 com.apple.CoreFoundation 0x948fe80d CFMergeSortArray + 125
10 com.apple.Foundation 0x994153d3 _sortedObjectsUsingDescriptors + 639
11 com.apple.Foundation 0x994150d8 -[NSArray(NSKeyValueSorting) sortedArrayUsingDescriptors:] + 566
Run Code Online (Sandbox Code Playgroud)
对我来说,这是一个NSIndexPath试图将自己与解除分配的实例进行比较的实例.
到目前为止,我所得到的最佳答案正如我所怀疑的:
\n\n从 OS X 10.7 和 iOS 5 开始,NSIndexPath是线程安全的。在此之前,实例是线程安全的,因为它们是不可变的,但现有实例的共享检索却不是。
对于按需返回索引路径的方法,我这样做了:
\n\n- (NSIndexPath *)indexPath;\n{\n NSIndexPath *result = \xe2\x80\xa6 // create the path as appropriate\n\n return [[result retain] autorelease];\n}\nRun Code Online (Sandbox Code Playgroud)\n\n自从实现最后一行代码以来,我们再也没有收到来自索引路径的崩溃报告。
\n\n-indexPathByAddingIndex:索引路径由or创建+indexPathWithIndex:。
我看到的结果让我非常确定(10.7/iOS5 之前)这些方法正在返回现有NSIndexPath实例。不过,当前线程不会以任何方式保留该实例,因此首先创建该实例的线程(在我们的例子中是 main )正在释放路径(可能通过弹出自动释放池)并为我们的工作线程留下一个悬空指针,正如问题中所见,使用时会崩溃。
这一切都有点可怕,因为如果我的分析是正确的,我添加的retain/autorelease舞蹈只是将一种竞争条件替换为另一种不太可能的竞争条件。
在 10.7/iOS5 之前,我只能想到一种真正的解决方法:将所有索引路径的创建限制到主线程。如果此类代码被多次调用,这可能会相当慢,因此可以通过维护自己的某种实例缓存以供后台线程使用,以内存 \xe2\x80\x94 为代价来改进 \xe2\x80\x94 。如果缓存保留路径,那么您就知道它不会被主线程释放。
\n| 归档时间: |
|
| 查看次数: |
915 次 |
| 最近记录: |