[英]NSFileHandle writeData synchronously delaying main thread operations
I have a custom implementation of a logger, which logs the actions and operations in my app. 我有一个记录器的自定义实现,它在我的应用程序中记录操作和操作。
A strong NSString
reference is living in one of my Singleton Classes. 我的Singleton类中有一个强大的NSString
引用。
I call a method named " -(void)writeToFile: (BOOL) rightNow
", whenever I need to log something. 每当需要记录某些内容时,我都会调用一个名为“ -(void)writeToFile: (BOOL) rightNow
”的方法。 This method also lives in that Singleton class. 此方法也存在于Singleton类中。
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
,将触发对NSFileHandle的writeData:
的立即调用,强制将NSString写入文件,然后清空NSString。
No, will only append the string and wait for a Yes
value in rightNow
to do the write operation. 否,将仅附加字符串并等待rightNow
的Yes
值执行写操作。
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
, rightNow
参数为YES
,我的应用就会暂停5/6分钟。
Similarly, If I call writeToFile
from a block (let's say a web service returned some data on a block), the app halts again. 同样,如果我从一个块调用writeToFile
(例如,Web服务在一个块上返回了一些数据),则该应用将再次暂停。
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). 据我了解,由于writeData
同步工作,由于某种原因,它在从块或计时器(假定在不同线程上调用)中调用时会中断。
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? 我可以将我的writeToFile
调用包装在GCD周围,但是如果我正在请求的线程(主线程/全局线程),当前状态仅仅是该怎么办? Wouldn't it create a deadlock calling main thread on main thread? 它不会在主线程上创建调用主线程的死锁吗?
Code: 码:
- (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 = @"";
}
}
Since your logging takes 5/6 mins, and halts subsequent operations in your app, simply move the logging to another queue with GCD: 由于您的日志记录需要5/6分钟,并且会停止应用程序中的后续操作,因此只需使用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];
});
At this point, it doesn't make any difference calling writeToFile
with YES
or NO
as rightNow
parameter; 在这一点上,它不会使任何区别通话writeToFile
用YES
或NO
作为rightNow
参数; you could always use YES
你总是可以用YES
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.