我在iOS应用中使用MoPub进行广告调解。我收到了一些用户对广告加载时阻止用户界面的投诉。我只能在某些低质量的网络条件下复制这个。
我天真的假设是我所要做的只是通过MPAdView.loadAd
从后台线程调用dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
,并使用dispatch_async(dispatch_get_main_queue()
代表中的adViewDidLoadAd
更新用户界面方法(在MoPubSDK加载广告时调用)。
但事实证明,这不起作用 - 委托方法永远不会被调用。
我将问题追溯到MoPubSDK,其中NSURLConnection
通过以下方式初始化:
self.connection = [NSURLConnection connectionWithRequest:[self adRequestForURL:URL] delegate:self];
但是NSURLConnectionDelegate
方法(如connectionDidFinishLoading
)本身在后台线程上执行时从不被调用。它在主线程上进行调用时有效。
我注意到"当前模式" [NSRunLoop currentRunLoop]
是"(无)"当在后台线程上执行时,但是" kCFRunLoopDefaultMode"在主线程上执行时。
NSURLConnection文档提到
为使连接正常工作,调用线程的运行循环必须以默认的运行循环模式运行。
所以我尝试使用
明确设置它 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[[NSDate alloc] initWithTimeIntervalSinceNow:60]];
但这没有效果。
那么,我需要做些什么来确保在后台线程中初始化连接时调用NSURLConnection委托方法?
答案 0 :(得分:0)
好的,经过几个小时的搜索,我写了这个问题 - 当然,15分钟后,我在SO找到了一个可能的解决方案......
self.connection = [[NSURLConnection alloc] initWithRequest:[self adRequestForURL:URL] delegate:self startImmediately:NO];
NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
[self.connection scheduleInRunLoop:runLoop forMode:NSRunLoopCommonModes];
[self.connection start];
[runLoop run];
这可确保调用NSURLConnection委托方法。
(我现在有一个不同的问题"这可能是从辅助线程调用UIKit的结果。" - 但这与原始问题无关。)
答案 1 :(得分:0)
您可能应该在主运行循环而不是当前循环上调度连接对象。这不仅可以避免在非功能运行循环上安排它的问题(这是什么?),而且还将确保在请求完成时,广告框架不会尝试在错误的线程上执行UI操作。