NSFileHandle writeData同步延迟主线程操作 [英] NSFileHandle writeData synchronously delaying main thread operations

查看:102
本文介绍了NSFileHandle writeData同步延迟主线程操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个记录器的自定义实现,该记录器记录了我的应用程序中的操作和操作.

I have a custom implementation of a logger, which logs the actions and operations in my app.

强大的NSString参考生活在我的Singleton课堂之一中.

A strong NSString reference is living in one of my Singleton Classes.

每当我需要记录某些内容时,我都会调用一个名为"-(void)writeToFile: (BOOL) rightNow"的方法.这种方法也存在于Singleton类中.

I call a method named "-(void)writeToFile: (BOOL) rightNow", whenever I need to log something. This method also lives in that Singleton class.

传递给rightNow的是,将触发对NSFileHandle上的writeData:的立即调用,强制将NSString写入文件,然后清空NSString.

Yes passed to rightNow, will trigger the immediate call to writeData: on NSFileHandle, forcing the NSString to be written to the file and emptying the NSString afterwards.

否,将仅追加字符串并等待rightNow中的Yes值进行写操作.

No, will only append the string and wait for a Yes value in rightNow to do the write operation.

每当我通过计时器调用的方法调用writeToFile时,将rightNow参数设为YES,我的应用就会暂停5/6分钟.

Whenever I call writeToFile from a method which is being called through a timer, with rightNow param as YES, my app halts for 5/6 mins.

类似地,如果我从一个块调用writeToFile(例如,Web服务在一个块上返回了一些数据),则该应用程序再次暂停.

Similarly, If I call writeToFile from a block (let's say a web service returned some data on a block), the app halts again.

据我了解,由于writeData是同步工作的,由于某种原因,它在从块或计时器(我假设是在不同线程上调用)中调用时会中断.

To my understanding, since writeData works synchronously, for some reason, it breaks when called from block or timers (which I am assuming are called on different threads).

这是预期的行为吗?我可以将我的writeToFile调用包装在GCD周围,但是如果我正在请求的线程(主/全局),当前状态仅仅是该怎么办?它不会在主线程上创建调用主线程的死锁吗?

Is this the expected behavior? I could wrap my writeToFile call around GCD, but what if the thread I am requesting (main/global), the current state is that only? Wouldn't it create a deadlock calling main thread on main thread?

代码:

- (void) writeToFile: (NSString *) targetString rightNow: (BOOL) rightNow
{
    //_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 (rightNow)
    {
        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 = @"";
    }
}

推荐答案

由于您的日志记录需要5/6分钟,并且会停止应用程序中的后续操作,因此只需使用GCD将日志记录移至另一个队列即可:

Since your logging takes 5/6 mins, and halts subsequent operations in your app, simply move the logging to another queue with GCD:

dispatch_queue_t loggingQueue = dispatch_queue_create("MyLoggingQueue", DISPATCH_QUEUE_SERIAL);

,然后始终在该队列上执行日志记录:

and then, perform the logging always on that queue:

dispatch_async(loggingQueue, ^(void){
    [TheLoggerSingleton writeToFile:@"LogMe" rightNow:YES];
});

在这一点上,用YESNO作为rightNow参数调用writeToFile并没有什么区别;您可以随时使用YES

At this point, it doesn't make any difference calling writeToFile with YES or NO as rightNow parameter; you could always use YES

这篇关于NSFileHandle writeData同步延迟主线程操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆