Обрабатывать метод writeData для NSFileHandle в основном потоке - PullRequest
0 голосов
/ 23 октября 2018

Поскольку writeData вызов является синхронным, как лучше всего использовать его, когда мы вызываем writeData из другого потока, отличного от основной очереди?

Например, вызывается веб-служба для получения некоторых данныхи завершениеHandler назначается для вызова веб-службы.Теперь этот обработчик завершения будет выполняться в другом потоке (не в основной очереди).

Я видел, как мое приложение зависло при методе writeData в течение 5-6 минут.Это единственное, что я могу заподозрить прямо сейчас.

Я пытался обернуть вокруг моего writeData звонка dispatch_async(mainQueue), но это не сработало.

- (void) writeToFile: (NSString *) targetString
{
    //_loggingString holds the data, which keeps on accumulating as the user performs operations. At some point of time (callbacks from API's I call this method, to actually, write this string in the file and clear this string afterwards.)
    NSString *oldString = [_loggingString copy];

    _loggingString = [oldString stringByAppendingString:targetString];

    if (![[NSFileManager defaultManager]fileExistsAtPath:@"somePath"])
    {
        [[NSFileManager defaultManager]createFileAtPath:@"somePath" contents:nil attributes:nil];
    }

    NSFileHandle *fileHandle =  [NSFileHandle fileHandleForWritingAtPath:@"somePath"];

    [fileHandle seekToEndOfFile];

    [fileHandle writeData:[_loggingString dataUsingEncoding:NSUTF8StringEncoding]];

    _loggingString = @"";
}

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Не рекомендуется делать операцию записи файла в основном потоке.Кроме того, будет проблема с производительностью глобальной очереди по умолчанию, так как система не может установить приоритетность задачи.

Поэтому попробуйте создать 4 типа фоновых очередей:

dispatch_queue_t GlobalUserInteractiveQueue(void) {
    return dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0);
}

dispatch_queue_t GlobalUserInitiatedQueue(void) {
    return dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0);
}

dispatch_queue_t GlobalUtilityQueue(void) {
    return dispatch_get_global_queue(QOS_CLASS_UTILITY, 0);
}

dispatch_queue_t GlobalBackgroundQueue(void) {
    return dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0);
}

В вашем коде простосделать это:

создать пользовательскую очередь. queue = dispatch_queue_create("customQueueName", NULL);

затем напишите код в асинхронной отправке

dispatch_async( queue ,
                   ^ {
                       // execute asynchronously
                       [fileHandle seekToEndOfFile];
                       [fileHandle writeData:[_loggingString dataUsingEncoding:NSUTF8StringEncoding]];

                   }); 

Проверьте рабочий процесс каждой очереди здесь: https://gist.github.com/ankitthakur/dd945a66924fbd697169

0 голосов
/ 23 октября 2018

Вы можете сохранить часть в потоке BackGround

- (void) writeToFile: (NSString *) targetString
{

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSString *oldString = [_loggingString copy];

    _loggingString = [oldString stringByAppendingString:targetString];

    if (![[NSFileManager defaultManager]fileExistsAtPath:@"somePath"])
    {
        [[NSFileManager defaultManager]createFileAtPath:@"somePath" contents:nil attributes:nil];
    }

    NSFileHandle *fileHandle =  [NSFileHandle fileHandleForWritingAtPath:@"somePath"];

    [fileHandle seekToEndOfFile];

    [fileHandle writeData:[_loggingString dataUsingEncoding:NSUTF8StringEncoding]];

    _loggingString = @"";

});
}
...