1

I have written 2 methods:

  1. WriteToLogFile

  2. 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?

soumya
  • 3,801
  • 9
  • 35
  • 69
sulabh
  • 249
  • 5
  • 22

1 Answers1

0

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.

Mehul Parmar
  • 3,599
  • 3
  • 26
  • 42
  • 1
    Thanks mehul for the suggesttion using same logQueue works good. but only thing is its now have bcome more time consuming .anyways i will accept your solution. – sulabh Aug 05 '15 at 11:33
  • thats because all your tasks are now lined up within the same serial dispatch queue... I am not really sure as to what exactly are you trying to achieve/prove with the above code, but one solution could be to dispatch_async on system concurrent queues, and have semaphores (dispatch_semaphore_t) across the critical fileHandle code. – Mehul Parmar Aug 05 '15 at 12:40