NSFileManager crashing in app delegate
I have this code in a method called from applicationDidFinishLaunching. It works in the simulator, but crashes on the iPhone. There are about 1,600 2KB mp3 files being copied in this operation. If I try to instantiate the app multiple times, it will eventually copy more each time until the app eventually will start without crashing. I am releasing everything I allocate. I have about 20GB disk space free on the iPhone. If I progressively comment out code and run it on the iPhone, the copyItemAtPath seems to be the suspect.
- (void)createCopyOfAudioFiles:(BOOL)force {
@try {
NSError *error;
NSString *component;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory开发者_StackOverflow社区, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSEnumerator *enumerator = [[[NSBundle mainBundle]pathsForResourcesOfType:@"mp3" inDirectory:nil] objectEnumerator];
while ((component = [enumerator nextObject]) != nil) {
NSArray *temp = [component componentsSeparatedByString:@".app/"];
NSString *file = [NSString stringWithFormat:@"%@", [temp objectAtIndex:1]];
NSString *writableAudioPath = [documentsDirectory stringByAppendingPathComponent:file];
BOOL success = [fileManager fileExistsAtPath:writableAudioPath];
if (success && !force) {
continue;
} else if (success && force) {
success = [fileManager removeItemAtPath:writableAudioPath error:&error];
}
success = [fileManager copyItemAtPath:component toPath:writableAudioPath error:&error];
if (!success) {
@throw [NSException exceptionWithName:[error localizedDescription] reason:[error localizedFailureReason] userInfo:nil];
}
}
[fileManager release];
}
@catch (NSException *exception) {
NSLog(@"%@", exception);
@throw [NSException exceptionWithName:exception.name reason:exception.reason userInfo:nil];
}
@finally {
}
}
The OS will kill your app if it fails to launch in a certain amount of time. Try doing your copy on a background thread.
Since you are doing this all in a loop, the autorelease pool is probably filling up. Either manually flush the autorelease pool or manually release the memory:
NSData data = [[NSData alloc] initWithContentsOfFile:component];
[data writeToFile:writableAudioPath atomically:NO];
[data release];
NSFileManager *fileManager = [[NSFileManager alloc] init];
A stab in the dark, but have you tried using the non thread safe version of NSFileManager:
NSFileManager* filemanager = [NSFileManager defaultManager];
You are probably getting killed by the iOS watchdog, any app that takes too long to launch gets terminated. try calling the method with performSelector:withObject:afterDelay:
so that it runs after you have exited the didFinishLaunching method.
精彩评论