我們的應用程序在我們編寫的啓用了ARC的庫中遇到了雙發佈崩潰。在運行檢測之後,我們發現雙釋放發生在由2個線程訪問的對象上。如何阻止ARC釋放兩個線程共享的對象兩次?
所討論的對象首先在2個線程以外分配在一個初始化方法
objectX = [[NSData alloc] initWithBytes:barcodeBytes length:sizeof(barcodeBytes)];
線程A開始,並將其添加到目標x一個NSDictionary。
線程B assignes _對象到本地的NSData指針和使用removeObjectAtIndex
,我們已經通過運行NSZombie注意到的是,目標x目前正在自動釋放兩次從共享的NSDictionary去除_對象。看起來,一個版本直接發佈在對象上,另一個版本是在包含它的NSDictionary被釋放時間接完成的。
首次發行:
0 libobjc.A.dylib -[NSObject release]
1 libobjc.A.dylib (anonymous namespace)::AutoreleasePoolPage::pop(void*)
2 libobjc.A.dylib (anonymous namespace)::AutoreleasePoolPage::tls_dealloc(void*)
3 libsystem_pthread.dylib _pthread_tsd_cleanup
4 libsystem_pthread.dylib _pthread_exit
5 libsystem_pthread.dylib pthread_exit
6 Foundation +[NSThread exit]
7 TestApp 0x348e72
8 Foundation __NSThread__main__
9 libsystem_pthread.dylib _pthread_body
10 libsystem_pthread.dylib _pthread_start
11 libsystem_pthread.dylib thread_start
第二個版本:
0 libobjc.A.dylib -[NSObject release]
1 CoreFoundation CFRelease
2 CoreFoundation -[__NSDictionaryM dealloc]
3 libobjc.A.dylib objc_object::sidetable_release(bool)
4 libobjc.A.dylib -[NSObject release]
5 libobjc.A.dylib (anonymous namespace)::AutoreleasePoolPage::pop(void*)
6 libobjc.A.dylib (anonymous namespace)::AutoreleasePoolPage::tls_dealloc(void*)
7 libsystem_pthread.dylib _pthread_tsd_cleanup
8 libsystem_pthread.dylib _pthread_exit
9 libsystem_pthread.dylib pthread_exit
10 Foundation +[NSThread exit]
11 TestApp 0x348e72
12 Foundation __NSThread__main__
13 libsystem_pthread.dylib _pthread_body
14 libsystem_pthread.dylib _pthread_start
15 libsystem_pthread.dylib thread_start
最終的結果是_對象是雙釋放,它更應該有和我們看到的崩潰。有趣的是,我們只在arm64設備上看到這一點。
你不分享任何關於你的代碼的信息,所以不可能多說。魔鬼在細節中,而你根本沒有提到任何細節。有辦法處理在線程之間傳遞/共享對象,但誰知道你是否在使用它們? – matt