fzw*_*zwo 1 multithreading objective-c uitextview uikit ios
我需要做一个必须在主线程上发生的一系列可能的调用(因为否则UIKit会讨厌)."长"是指在iPad 3上每次持续运行10,000次.
显然,立即循环遍历所有这些可能不是最好的主意.
我不知道如何在主线程上执行所有这些,同时留下足够的呼吸空间来保持UIKit响应并且看门狗睡着了(即不会因为占用运行循环而终止).
有人有想法吗?我将瞄准iOS 5.
具体来说,我正在尝试做的是缓存UITextPositions,因为a UITextView显然采用非缓存的迭代方法来获取UITextPositions,这意味着它非常非常慢positionFromPosition:textview.beginningOfDocument offset:600011,但获取速度要快得多positionFromPosition:aPositionAt600000 offset:11.事实上,在我的测试案例中,前者需要超过100秒(在主线程上!),而后者几乎是瞬时的.
为什么要在主线程上执行此操作?典型的答案是在后台线程上执行这些操作,并将UI更新发送回主线程.例如,您可以使用Grand Central Dispatch:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// do my time consuming task and everytime it wants to update the UI,
// it should dispatch that back to the main queue, e.g.
for (NSInteger i = 0; i < 10000; i++)
{
// do my background work
// now update the UI
dispatch_async(dispatch_get_main_queue(), ^{
// update the UI accordingly
});
}
});
Run Code Online (Sandbox Code Playgroud)
更新:
听起来你必须在前台做这个,所以也许使用a NSTimer可能会更好.我不是一个大NSTimer家伙,但它可能看起来像下面这样.
首先,确保你有一个类实例变量:
NSTimer *_timer;
Run Code Online (Sandbox Code Playgroud)
接下来,您可以使用以下命令初始化它:
- (void)startTimer
{
_timer = [NSTimer timerWithTimeInterval:0.0 target:self selector:@selector(timerCallback:) userInfo:nil repeats:YES];
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
[runloop addTimer:_timer forMode:NSDefaultRunLoopMode];
}
Run Code Online (Sandbox Code Playgroud)
然后,这将调用timerCallback,可能在每次调用时处理单个UITextPosition:
- (void)timerCallback:(NSTimer*)theTimer
{
BOOL moreTextPositionsToCalculate = ...;
if (moreTextPositionsToCalculate)
{
// calculate the next UITextPosition
}
else
{
[self stopTimer];
}
}
Run Code Online (Sandbox Code Playgroud)
当你完成后,你可以像这样停止你的计时器:
- (void)stopTimer
{
[_timer invalidate];
_timer = nil;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2305 次 |
| 最近记录: |