我不太熟悉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来释放数组,但它不起作用。
答案 0 :(得分:1)
你是如何创建这个帖子的? 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(Grand Central Dispatch)比NSThread更有效地使用系统资源。 NSThread基于POSIX线程,创建起来非常昂贵,并且可以在设备的生命周期内占用物理内存。
NSOperationQueues已经在最近的操作系统版本中进行了重构,以便在幕后使用GCD,因此它们在内部同样有效,尽管在大多数情况下使用GCD比使用GCD更难。
答案 1 :(得分:0)
嗯,我认为答案很明显。请查看documentation。
许多程序会创建自动释放的临时对象。这些 对象添加到程序的内存占用,直到结束 块。在许多情况下,允许临时对象累积 直到当前事件循环迭代结束才导致 过度开销;但是,在某些情况下,您可以创建一个 大量临时对象大量增加内存 足迹和你想要更快地处置。在这些 在后一种情况下,您可以创建自己的自动释放池块。在 块的结尾,临时对象被释放,这通常是 导致他们的释放,从而减少程序的内存 足迹。
你可以看到这个question。
因此,解决方案是使用您的@autoreleasepool{}
,因为您正在创建许多临时对象。