背景
我的应用程序从网络流中提取数据,并更改屏幕上 UI 元素的值。一个元素是 UITextView,它用作传入数据的一种日志。只要应用程序收到具有传入数据性质的“HasBytesAvailable”NSStreamEvent,它就应该更新。(例如,如果传入的数据与蛋糕有关,则 textview 将更新为“6/22/12 8:00 - got cake”)下面显示了它如何更新的示例。
[logString insertString:@"This is an update\n" atIndex:0];
//logstring is a MutableString I use to hold my UITextView's text
[logString insertString:timeString atIndex:0]; //timestring is current time
logView.text = logString; //logView is my UITextView
[logView flashScrollIndicators];
//logstring and logview declaration and implementation
@property (nonatomic,retain) IBOutlet UITextView *logView;
@property (nonatomic,retain) NSMutableString *logString;
logString = [[NSMutableString alloc] initWithString:@"-logging started\n"];
问题
只要我不尝试滚动 TextView,更新就会按我的意愿进行。但是,如果我滚动浏览文本并按住它,大概足够长的时间让我的更新代码被调用,当我停止滚动时应用程序会崩溃。我可以很好地浏览文本,只是当它必须处理传入的数据包并且我仍在滚动时它会崩溃。此外,当我滚动时,没有其他内容会更新。应该由接收到的数据更新的所有标签保持不变。
我的想法
就好像应用程序无法同时处理滚动和处理传入数据一样。我不确定这是否是因为我在内存管理方面做错了,或者我需要覆盖一些滚动功能,或者完全是其他东西。任何帮助或想法表示赞赏。
解决方案
正如 trumpetlicks 所说,我需要为我的网络任务实现多线程来做到这一点,我做了以下工作:
在初始化中:
NSOperationQueue *networkQueue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(initNetworkCommunication) object:nil];
[networkQueue addOperation:operation];
[operation release];
在 initNetworkCommunication 中,初始化 CFSocketpair 和流之后:
[[NSRunLoop currentRunLoop] run]; //necessary to handle stream events