I have written 2 methods:
WriteToLogFile
DeleteLogFile
and I am using NSFileHandle
for this
My Code is written as:
- (void)WriteToLogFile:(NSString *)string {
dispatch_async(logQueue ,^ {
if (nil == fileHandle) {
// log file not opened
NSLog(@"LogFile not opened");
return;
}
[fileHandle seekToEndOfFile];
[fileHandle writeData:[string dataUsingEncoding:NSUTF8StringEncoding]];
});
}
And other function to delete as:
-(void) deleteLogDataFromFile
{
NSString *logFilePath = [self getLogFilePath];
NSFileManager *fileManager = [NSFileManager defaultManager];
if([fileManager fileExistsAtPath:logFilePath])
{
[[NSFileManager defaultManager] createFileAtPath:logFilePath contents:[NSData data] attributes:nil];
fileHandle = [NSFileHandle fileHandleForWritingAtPath:logFilePath];
}
}
Now I am calling these 2 methods from a loop to check if it crashes at some point where it fileHandle will try to Write to file and will found no such file exist
for (int i = 0; i<1000; i++) {
[self WriteToLogFile:@"Hello"];
[self DeleteLogs];
}
And Xcode throws me error b/w loop is running
Terminating app due to uncaught exception 'NSFileHandleOperationException', reason: '*** -[NSConcreteFileHandle writeData:]: Bad file descriptor'
So I need to know how should I make my Write to file Or Delete to file work together , I know I should do some locking on fileHandle. Can anyone tell what should be done in order to fix this issue?
A simple dispatch_async(logQueue ,^ {...});
in deleteLogDataFromFile method should do the trick. (assuming logQueue s a serial dispatch queue).
For additional safety, consider making fileHandle a property in the class. Then override the getter, use
@ synchronized(_fileHandle){
return _fileHandle
}
And finally, use self.fileHandle in WriteToLogFile method.