在主线程上处理NSFileHandle上的writeData方法

时间:2018-10-23 08:05:55

标签: ios objective-c iphone grand-central-dispatch

由于writeData调用是同步的,所以当我们从主队列以外的其他线程调用writeData时,使用它的最佳方法是什么?

例如,调用Web服务以获取一些数据,并将完成处理程序分配给Web服务调用。现在,此完成处理程序将在其他线程上执行(不在主队列上执行)。

我发现我的应用在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 :(得分:0)

您可以在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 = @"";

});
}

答案 1 :(得分:0)

不建议在主线程中执行文件写入操作。另外,默认的全局队列会导致性能出现问题,因为系统无法确定任务的优先级。

因此,尝试创建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