我不太熟悉Objective-C,因此如果这是一个愚蠢的问题,请原谅我。我创建了一个后台线程来解析目录中存在的文件列表,该目录中的文件可以随时更改。
我在循环的每次迭代中都调用“contentsOfDirectoryAtPath”,而我的分配突然超过了300mb。我不知道如何使ARC释放返回的数组。有人可以在这里指出正确的方向吗?
-(void) offlineModeThread
{
NSString *dataDir = [ViewController getDataDirectory];
NSFileManager *nfm = [NSFileManager defaultManager];
while(1)
{
NSArray *files = [nfm contentsOfDirectoryAtPath:dataDir error:nil];
/*
if(files == nil)
break;
if([files count] <= 0)
{
files = nil;
[NSThread sleepForTimeInterval: 5.0f];
continue;
}
if(![ViewController obtainLock])
{
files = nil;
continue;
}
*/
//[ViewController releaseLock];
files = nil;
}
}
如您所见,我尝试通过将'files'设置为nil来释放数组,但是它不起作用。
最佳答案
您如何创建此线程? NSThread? NSOperation和NSOperationQueue? GCD?
对于NSThread和NSOperation,应该在设置线程的过程中创建自己的自动释放池。这样,可以在该线程内正确管理临时对象。
我相信GCD会为您处理这个细节。
在Objective C的较新版本(我相信Objective C 2.0)中,应使用新语法
@autoreleasepool
{
//Code to use a local autorelease pool
}
对于生成大量临时对象的循环,可以为任何代码块创建本地自动释放池。您可以这样重构代码:
while(1)
{
@autoreleasepool
{
NSArray *files = [nfm contentsOfDirectoryAtPath:dataDir error:nil];
/*
if(files == nil)
break;
if([files count] <= 0)
{
files = nil;
[NSThread sleepForTimeInterval: 5.0f];
continue;
}
if(![ViewController obtainLock])
{
files = nil;
continue;
}
*/
//[ViewController releaseLock];
files = nil;
}
}
这将导致它为循环的每次迭代创建一个新的自动释放池,并在最后将其耗尽(从而释放该迭代中创建的所有临时对象)。
顺便说一句,如果您使用的是NSThread,请不要使用。了解如何改为使用GCD。 GCD(大中央调度)使MUCH比NSThread更有效地利用系统资源。 NSThread基于POSIX线程,这在创建时非常昂贵,并且会在应用程序生命周期内占用设备上的物理内存。
NSOperationQueues在最近的OS版本中已经过重构,可以在后台使用GCD,因此它们在内部的效率也类似,尽管在大多数情况下比GCD难使用。
关于ios - iOS —调用contentsOfDirectoryAtPath会在循环中泄漏内存,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20134951/