0

NSFileManagerを使用してバックグラウンドスレッドでファイルサイズを取得すると、奇妙なクラッシュが発生します。

localFileSizeという曲オブジェクトのプロパティがあります。

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

オーディオ再生を処理するクラス(AQSやCore Audioではなくサードパーティのオーディオライブラリを使用)には、メインスレッドではなく、オーディオライブラリの再生スレッドで呼び出されるファイル長のコールバック関数があります。

そのファイル長関数では、@autoreleasepool内のsongオブジェクトの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以降をサポートしていますが、すべてのクラッシュレポートはiOS5.0.1および5.1からのものであることに注意してください。では、iOS 5のバグの可能性はあるのでしょうか?

4

3 に答える 3

1

それはいつ変わったのだろうか?[NSFileManagerdefaultManager]がスレッドセーフではないことをはっきりと覚えています。ちなみに、複数のスレッドからdefaultManagerを呼び出す場合にも同じ問題が発生します。他の人も同じように覚えているようです:http://useyourloaf.com/blog/2011/06/12/nsfilemanager-defaultmanager-is-not-thread-safe.html

于 2012-08-23T20:12:40.567 に答える
0

+defaultManagerfromバックグラウンドスレッドは使用しないでください。インスタンスをalloc+initして使用し、(ARCを使用していない場合は)リリースするだけです。それはちょうど間違っていました。

于 2012-04-23T23:29:53.760 に答える
0

ファイルサイズを取得するために次のようなものを使用することになりました:

#include <sys/stat.h>

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

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

または、ドキュメントがスレッドセーフについて完全に真実ではないように見えるため、新しいNSFileManagerオブジェクトを作成してみることができます。

于 2012-08-23T20:46:05.993 に答える