I am building a Mac Application with Xcode that has a very long lasting loop in one of the methods. I use the loop inside an Autoreleasing Pool (@autoreleasepool) but my app still eventually runs out of memory.
My application executes a thread in the background and uses NSDirectoryEnumerator that runs a system wide file search and changes every icon (using NSWorkspace) of every file on the entire system and constantly update a textfield with the file path changed. This is obviously why its running out of memory but I want to know how I can stop it from using up memory without freeing it.
Here is my source code:
NSImage *newFileIcon = ...;
NSImage *newFolderIcon = ...;
NSString *sourcePath = [@"/" stringByExpandingTildeInPath];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *directoryURL = [NSURL fileURLWithPath:sourcePath];
NSArray *keys = [NSArray arrayWithObject:NSURLIsDirectoryKey];
[[NSWorkspace sharedWorkspace] setIcon:newFolderIcon forFile:[directoryURL path] options:NSExcludeQuickDrawElementsIconCreationOption];
NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtURL:directoryURL includingPropertiesForKeys:keys options:0 errorHandler:^(NSURL *url, NSError *error) {return YES;}];
@autoreleasepool {
for (NSURL *url in enumerator) {
NSError *error;
NSNumber *isDirectory = nil;
if (![url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error]) {
NSLog(@"Error!"); // File Error
} else if (![isDirectory boolValue]) {
// Set File Icon
[[NSWorkspace sharedWorkspace] setIcon:newFileIcon forFile:[url path] options:NSExcludeQuickDrawElementsIconCreationOption];
// Update Status TextField
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self.statusField setStringValue:[NSString stringWithFormat:@"Changed File : \n%@", url.path]];});
// Log File Changed
NSLog(@"Changed File : %@", [url path]);
} else if ([isDirectory boolValue]) {
// Set Folder Icon
[[NSWorkspace sharedWorkspace] setIcon:newFolderIcon forFile:[url path] options:NSExcludeQuickDrawElementsIconCreationOption];
// Update Status TextField
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self.statusField setStringValue:[NSString stringWithFormat:@"Changed Folder : \n%@", url.path]];});
// Log Folder Changed
NSLog(@"Changed Folder : %@", [url path]);
}
}
}
Thanks