gpt4 book ai didi

iOS UIScrollView 因 NSRunLoopCommonModes 而卡住且无响应

转载 作者:可可西里 更新时间:2023-11-01 05:58:00 25 4
gpt4 key购买 nike

在我的 iPhone 应用程序中,我为 WebSockets 网络使用了第 3 方库 (libPusher),该库导致我的应用程序中的每个 UIScrollView 组件都变得无响应。这包括 UIScrollViews 和 UITableView。

发生的情况是,如果用户用他的手指滚动其中一个 UIScrollView 组件,并且碰巧在网络操作正在进行的同时用他的手指继续触摸和滑动 View ,那么这会导致完全无响应UIScrollView 停止接受触摸事件(它认为它一直处于拖动模式,即使手指抬起)并且没有适当减速。唯一的出路是销毁 UIScrollView 并重新创建一个新的。

我已经联系了库的开发人员,但不幸的是到目前为止还没有收到回复。

根据我的阅读,这是在不合适的模式(例如 NSDefaultRunLoopMode)下运行运行循环时的常见问题,但是这个库似乎正在做正确的事情,它在 NSRunLoopCommonModes 中运行它的运行循环,所以我不清楚正确的解决方案是什么。

我尝试过不同的模式(尝试过 NSDefaultRunLoopMode),但行为是一样的。

我使用的是 iOS 5,它在模拟器和设备上的行为相同。

让我将我认为有问题的代码粘贴到库中,希望它的范围足以让您帮助我找到解决方案。

在 NSOperation 的子类中我们有:

- (void)start 
{
NSAssert(URLRequest, @"Cannot start URLRequestOperation without a NSURLRequest.");

[self setExecuting:YES];

URLConnection = [[NSURLConnection alloc] initWithRequest:URLRequest delegate:self startImmediately:NO];

if (URLConnection == nil) {
[self setFinished:YES];
}

// Common modes instead of default so it won't stall uiscrollview scrolling
[URLConnection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[URLConnection start];

do {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
} while (!_isFinished);
}

此操作在 main 线程上运行,如 [[NSOperationQueue mainQueue] addOperation:authOperation]; 所示。 (也许这就是问题所在,但我尝试在另一个线程中运行它,但它崩溃了,因此该库将需要更多工作才能使其成为后台线程安全的,所以我还不能证明这是解决方案...)

到目前为止我已经尝试过了

  • 将运行循环模式更改为 NSDefaultRunLoopMode - 没有帮助。
  • 在我创建的新操作队列中运行操作(例如,不在主线程上),但库似乎没有为此做好准备,因为它崩溃了。

我仍然觉得我在黑暗中射击......帮助:)

谢谢!

最佳答案

它变得无响应,因为它在主线程上执行 while 循环。这是一个糟糕的设计模式。

既然你在 iOS5 上,为什么不使用 NSURLConnection 的 +sendAsynchronousRequest:queue:completionHandler: ?

如果您需要与 iOS4.x 兼容,我会去掉运行循环的内容并查看 this blog post .

基本上,我会做这样的事情:

- (void)start
{
if (![NSThread isMainThread]) {
return [self performSelectorOnMainThread:@selector(start)
withObject:nil
waitUntilDone:NO];
}

[self willChangeValueForKey:@"isExecuting"];
isExecuting = YES;
[self didChangeValueForKey:@"isExecuting"];

NSURLConnection *aConnection = [[NSURLConnection alloc] initWithRequest:request
delegate:self];

self.connection = aConnection;
[aConnection release];

if (connection == nil) {
// finish up here
}
}

关于iOS UIScrollView 因 NSRunLoopCommonModes 而卡住且无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8500562/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com