First off, I'd like to apologize in advance for not knowing this. I've been trying to get my head around the best way of dealing with memory management in this instance.
I have a short method for determining if a file should be added to a list. One of the checks requires a NSFileManager be instantiated. Because some checks could p开发者_JS百科otentially take a long time I want to jump out as soon as any of my conditions fail. However, if I return early my NSFileManager instance will never receive it's release message.
I've thought about using an AutoReleasePool but since objects added to autoreleasepools don't get released until the end of the current run loop and my program looks over many thousands of files per run loop I don't like leaving them all allocated until the end of the loop.
How can I ensure that each instance of my NSFileManager gets release appropriately. Any suggestions appreciated.
Thanks!
- (BOOL) fileShouldBeAdded:(NSString *)filePath { BOOL fileShouldBeAdded = TRUE; NSFileManager *fileManager = [[NSFileManager alloc] init]; if ([[filePath lastPathComponent] containsString:@"test.txt"]) { fileShouldBeAdded = FALSE; return fileShouldBeAdded; } if (![fileManager xAttrFileAtPathShouldBeAdded:filePath]) { fileShouldBeAdded = FALSE; return fileShouldBeAdded; } if ([[BackupManager sharedInstance] isExcludedByUser:filePath]) { fileShouldBeAdded = FALSE; return fileShouldBeAdded; } if (![fileManager backupRequiredForPath:filePath]) { fileShouldBeAdded = FALSE; return fileShouldBeAdded; } [fileManager release]; return fileShouldBeAdded; }
Refactor the function so the memory is managed in the outer method and the if inside e.g.
-(BOOL) checkFile: (NSFileManager*) fileManager withPath:(NSString *)filePath
{
if ([[filePath lastPathComponent] containsString:@"test.txt"]) {
return FALSE;
}
if (![fileManager xAttrFileAtPathShouldBeAdded:filePath]) {
return FALSE;
}
if ([[BackupManager sharedInstance] isExcludedByUser:filePath]) {
return FALSE;
}
if (![fileManager backupRequiredForPath:filePath]) {
return FALSE;
}
}
- (BOOL) fileShouldBeAdded:(NSString *)filePath {
NSFileManager *fileManager = [[NSFileManager alloc] init];
BOOL fileShouldBeAdded = [self checkFile:fileManager withPath:filePath];
[fileManager release];
return fileShouldBeAdded;
}
Since you say this is called many thousands of times, you are far better off allocating the NSFileManager
outside of the loop -- say, as an instance variable -- and then using that same instance throughout your loop.
You could pass it in as an argument a la Mark's solution, if you wanted.
Transient allocation traffic can be extremely detrimental to performance. But, of course, don't bother unless it is either terribly convenient or you've measured a problem.
精彩评论