Iphone 自动释放池排空时NSFileAttributes解除锁定中的SIGSEGV SEGV_ACCERR崩溃?

Iphone 自动释放池排空时NSFileAttributes解除锁定中的SIGSEGV SEGV_ACCERR崩溃?,iphone,objective-c,ios,ios5,Iphone,Objective C,Ios,Ios5,在后台线程中使用NSFileManager获取文件大小时,我遇到了一个奇怪的崩溃 我有一个名为localFileSize的song对象的属性: - (unsigned long long)localFileSize { return [[[NSFileManager defaultManager] attributesOfItemAtPath:self.currentPath error:NULL] fileSize]; } 在我处理音频播放的类中(使用第三方音频库,而不是AQS或Co

在后台线程中使用NSFileManager获取文件大小时,我遇到了一个奇怪的崩溃

我有一个名为localFileSize的song对象的属性:

- (unsigned long long)localFileSize
{
    return [[[NSFileManager defaultManager] attributesOfItemAtPath:self.currentPath error:NULL] fileSize];
}
在我处理音频播放的类中(使用第三方音频库,而不是AQS或Core audio),有一个文件长度回调函数在音频库的播放线程中调用,而不是在主线程中调用

在该文件长度函数中,我正在@autoreleasepool中读取我的歌曲对象的localFileSize属性。在函数结束时,当池被排空时,NSFileAttributes对象的dealloc方法有时会出现崩溃。我自己无法复制它,但我有14个关于这个问题的崩溃日志

以下是其中一个崩溃日志的相关部分:

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,但尚未发布更新。无论如何,我不认为这会对这个案子有什么影响


此外,值得注意的是,所有的崩溃报告都来自iOS 5.0.1和5.1,尽管我的应用程序支持4.2及以上版本。那么可能是某种iOS5错误

不要从后台线程使用
+defaultManager
。只需alloc+init实例,使用它,然后(如果不使用ARC)释放它。那是错的。

我想知道这是什么时候改变的?我清楚地记得[NSFileManager defaultManager]不是线程安全的。顺便说一句,我们在从多个线程调用defaultManager时也遇到了同样的问题。看起来其他人也以同样的方式记住了它:

最后使用类似的方法来获取文件大小:

#include <sys/stat.h>

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

stat(filename, &fileInfo);
fileSize = fileInfo.st_size;
#包括
结构统计文件信息;
关闭文件大小;//可以投到很长的时间
stat(文件名和文件信息);
fileSize=fileInfo.st\u size;

或者您可以尝试创建新的NSFileManager对象,因为这些文档可能并不完全符合线程安全的要求。

真的吗?说“共享
NSFileManager
对象的方法可以从多个线程安全地调用。”嗯,不知道。但无论如何,我改用C函数来获取文件信息,从那以后就没有任何问题了。