我注意到@autoreleasepool的一个非常奇怪的行为。
我有一个这个方法,主线程上的计时器每隔“n”秒调用一次。 该方法 - 简单地说 - 创建一个大型NSDictionary的副本并将其保存到给定路径的plist中。
所以,问题是在每次调用[snapshot writeToFile:pathname atomically:YES];
之后,我的应用程序的内存占用量增加了大约5-6 MB,即使在退出@autorelease
块之后也不会减少。
我无法理解问题是GCD,@ autoreleasepool,还是writeToFileName:atomically:,或者try / catch或者我是否犯了一些错误......
......我疯了。
有什么建议吗?
提前谢谢
罗布
-(void)serializeIndexDictionary
{
if (_indexDictionary != nil && _needsToSerialize == YES)
{
// save index dictionary
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
@autoreleasepool
{
@try
{
NSDate *start = [NSDate date];
NSString *pathname = [NSString stringWithFormat:@"%@/%@", _cacheBasePath, _cacheFilename];
// Per fare una copia ci mette zero-virgola mentre per salvare su file ci mette qualche secondo...
// In questo modo la sezione critica dura molto meno...
// ...e considerato che l'accesso all'indice blocca qualunque operazione, non mi pare cosa da poco.
NSDictionary *snapshot = nil;
@synchronized (self)
{
snapshot = [_indexDictionary copy];
_needsToSerialize = NO;
}
/*
* If flag is YES, the dictionary is written to an auxiliary file, and then the auxiliary file is renamed to path.
* If flag is NO, the dictionary is written directly to path. The YES option guarantees that path, if it exists at all,
* --> won’t be corrupted even if the system should crash during writing. <--
*/
[snapshot writeToFile:pathname atomically:YES];
snapshot = nil;
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager addSkipBackupAttributeToItemAtPath:pathname];
NSDictionary *attributes = [fileManager attributesOfItemAtPath:pathname error:nil];
unsigned long long fileSize = [attributes fileSize];
NSLog(@"%@: Index serialized (%lld bytes in %g seconds)", self, fileSize, [[NSDate date] timeIntervalSinceDate:start]);
}
@catch (NSException *exception)
{
NSString *message = [NSString stringWithFormat:@"%@: EXCEPTION CAUGHT\nDebug info:\n%@ (%@) [userInfo=%@]\n\nStack trace:\n%@",
NSStringFromSelector(_cmd), exception.name, exception.reason, exception.userInfo, [exception callStackSymbols]];
NSLog(@"%@", message);
}
@finally
{
// noop
}
}
});
}
}