2012-04-23 9 views
0

NSFileManagerを使用してバックグラウンドスレッドでファイルサイズを取得すると、異常なクラッシュが発生します。autoreleasepoolが流出したときにSIGSEGV SEGV_ACCERRがNSFileAttributesでクラッシュする

私はlocalFileSizeという曲オブジェクトのプロパティがあります(サードパーティのオーディオライブラリを使用して、ないAQSまたはCore Audio)の私のオーディオ再生を扱う私のクラスで

- (unsigned long long)localFileSize 
{ 
    return [[[NSFileManager defaultManager] attributesOfItemAtPath:self.currentPath error:NULL] fileSize]; 
} 

を、ファイルの長さがありますオーディオライブラリの再生スレッドで呼び出されるコールバック関数であり、メインスレッドではありません。

このファイル長関数では、@autoreleasepoolの中で、私の曲オブジェクトのlocalFileSizeプロパティを読んでいます。関数の最後にプールが排水されると、NSFileAttributesオブジェクトのdeallocメソッドでクラッシュすることがあります。私はそれを自分で再現することはできませんが、私はこの問題で14のクラッシュログを持っています。ここで

は、クラッシュログの1の関連部分である:

Thread 8 Crashed: 
0 libobjc.A.dylib      0x3262c4e8 _ZN4objc8DenseMapIP11objc_objectmLb1ENS_12DenseMapInfoIS2_EENS3_ImEEE4growEj + 67 
1 libobjc.A.dylib      0x32638d81 _ZN4objc8DenseMapIP11objc_objectmLb1ENS_12DenseMapInfoIS2_EENS3_ImEEE16InsertIntoBucketERKS2_RKmPSt4pairIS2_mE + 56 
2 libobjc.A.dylib      0x3262b09d _ZN4objc8DenseMapIP11objc_objectmLb1ENS_12DenseMapInfoIS2_EENS3_ImEEE16FindAndConstructERKS2_ + 44 
3 libobjc.A.dylib      0x3262b139 _objc_rootReleaseWasZero + 92 
4 libobjc.A.dylib      0x3262b0ad _objc_rootRelease + 12 
5 Foundation       0x31fbab81 -[NSFileAttributes dealloc] + 60 
6 libobjc.A.dylib      0x3262b0c5 _objc_rootRelease + 36 
7 libobjc.A.dylib      0x3262cdb7 objc_release + 38 
8 libobjc.A.dylib      0x3262be0d _ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv + 224 
9 libobjc.A.dylib      0x3262bd29 _objc_autoreleasePoolPop + 12 
10 CoreFoundation      0x35b0ce8f _CFAutoreleasePoolPop + 18 
11 Foundation       0x31f8aaf1 -[NSAutoreleasePool drain] + 128 
12 iSub        0x000fb6cb MyFileLenProc (AudioEngine.m:320) 
13 iSub        0x001623d8 BASS_FX_TempoCreate + 5160 
14 iSub        0x0016261c BASS_FX_TempoCreate + 5740 
15 iSub        0x0017f42c BASS_ChannelIsActive + 27424 
16 AudioToolbox      0x364905d9 _ZN19AudioConverterChain19DirectCallInputProcEPmS0_P15AudioBufferListPPK28AudioStreamPacketDescription + 228 
17 AudioToolbox      0x36465ee3 _ZN14CodecConverter13CallInputProcERm + 266 
18 AudioToolbox      0x3646588d _ZN14CodecConverter17DecoderFillBufferERmR15AudioBufferListP28AudioStreamPacketDescription + 576 
19 AudioToolbox      0x36465649 _ZN14CodecConverter10FillBufferERmR15AudioBufferListP28AudioStreamPacketDescription + 28 
20 AudioToolbox      0x36452c99 _ZN19AudioConverterChain12RenderOutputEP12CABufferListmRmP28AudioStreamPacketDescription + 92 
21 AudioToolbox      0x36452b53 _ZN22BufferedAudioConverter10FillBufferERmR15AudioBufferListP28AudioStreamPacketDescription + 186 
22 AudioToolbox      0x36452929 AudioConverterFillComplexBuffer + 356 
23 iSub        0x0017d9f8 BASS_ChannelIsActive + 20716 
24 iSub        0x00184f70 BASS_ChannelSetPosition + 640 
25 iSub        0x00186eb4 BASS_ChannelGetData + 1032 
26 iSub        0x000fc787 __35-[AudioEngine keepRingBufferFilled]_block_invoke_0 (AudioEngine.m:752) 
27 libdispatch.dylib     0x35e3fd55 _dispatch_call_block_and_release + 12 
28 libdispatch.dylib     0x35e4b7a3 _dispatch_worker_thread2 + 262 
29 libsystem_c.dylib     0x30fbb1cf _pthread_wqthread + 294 

これを引き起こしている可能性がどのような任意のアイデア?

また、何らかの違いがある場合、これらのクラッシュが報告された時点で、プロジェクトはARCを使用していませんでした。私は最近ARCに変換しましたが、まだアップデートをリリースしていません。とにかくこのケースでは違いはありません。

また、私のアプリが4.2以上をサポートしていても、すべてのクラッシュレポートはiOS 5.0.1と5.1からのものであることに注意してください。だから、潜在的にiOS 5のバグがありますか?

答えて

0

::他の人がそれを同じように覚えているように見えます

#include <sys/stat.h> 

struct stat fileInfo; 
off_t fileSize; // Can cast to long long 

stat(filename, &fileInfo); 
fileSize = fileInfo.st_size; 

それともそれはドキュメントがないかもしれ表示されるあなたは、新しいNSFileManagerオブジェクトを作成してみてくださいすることができますスレッドの安全性について完全に真実であること。

0

バックグラウンドスレッドから +defaultManagerを使用しないでください。インスタンスをalloc + initするだけでそれを使用し、(ARCを使用していない場合は)解放してください。 それは間違っていた。

+1

本当に? https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/nsfilemanager_Class/Reference/Reference.html "共有された' NSFileManager'オブジェクトのメソッドは、複数のスレッドから安全に呼び出すことができます" –

+0

ええ、そうです。私は私の答えを撤回する。 –

1

いつ変更されましたか?私は[NSFileManager defaultManager]がスレッドセーフではないことを明確に覚えています。ところで、複数のスレッドからdefaultManagerを呼び出すのと同じ問題が発生しています。ファイルのサイズを取得するには、このようなものを使用して終了http://useyourloaf.com/blog/2011/06/12/nsfilemanager-defaultmanager-is-not-thread-safe.html

+0

うーん、考えていない。しかし、いずれにせよ、私はファイル情報を取得するためにC関数を使用することに切り替えて以来、何の問題もありませんでした。 –

関連する問題