我有一个应用程序可以同时将图像上传到一堆地方,有点像Instagram风格。
使用NSOperationQueue
进行设置,在异步NSOperation
周围运行一堆NSURLConnection
个包装器。
大多数问题都是这样开始的“回调不会被调用,因为调用线程在它们返回之前已经连接。这是不那样的问题。我 am < / em>按预期收到我的回调,但是当按下主页按钮时,我也会以某种方式阻止应用程序进行后台处理。我一直认为由于沙盒而无法阻止它,但不知怎的,我已经完成了它。操作正在运行时的主页按钮在完成之前不会执行任何操作,此时(20-30秒后)应用程序将正确显示背景。
** NB这似乎只发生在单核处理器设备上。我只能在我的iPhone 4上重现,但不能在我的4S或iPad 3上重现。*
还有兴趣吗?这是我的设置:
self.uploadQueue = [[NSOperationQueue alloc] init];
[self.uploadQueue setMaxConcurrentOperationCount:1];
[self.uploadQueue setSuspended:YES];
稍后,我将操作添加到队列中,然后将其取消挂起以启动。以下是NSOperation
子类的一些代码:
- (BOOL)isConcurrent { return YES; }
- (BOOL)isExecuting { return self.executing; }
- (BOOL)isFinished { return self.finished; }
- (void)start {
// Omitted: check for cancel...
// Omitted: check if setup to run
[self willChangeValueForKey:@"isExecuting"];
self.executing = YES;
[self didChangeValueForKey:@"isExecuting"];
[self.sharer share];
CFRunLoopRun();
}
- (void)completeOperation {
[self willChangeValueForKey:@"isFinished"];
[self willChangeValueForKey:@"isExecuting"];
self.executing = NO;
self.finished = YES;
[self didChangeValueForKey:@"isExecuting"];
[self didChangeValueForKey:@"isFinished"];
CFRunLoopStop(CFRunLoopGetCurrent());
}
share
方法设置异步NSURLConnection
并将其关闭,如下所示:
- (void)share {
// Omitted: connection setup
[NSURLConnection sendAsynchronousRequest:postRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *responseData, NSError *error){
// handle error or success, then call
[self.currentOperation completeOperation];
}];
除了我试图解决的副作用之外,代码工作,因为它完成了它应该做的事情,回调被调用,线程保持活着,只要它们需要to,并且操作队列一次只运行指定数量的操作。
我尝试了什么?我试过了:
[NSOperationQueue currentQueue]
上调用NSURLConnection。这导致异步连接不回调块。start
方法中强制每个NSOperation到主线程。这并没有解决问题,也导致代码有时无法工作,UI有时会冻结。在按下主页按钮之后暂停执行,但在操作完成之前不会产生任何有趣的事情。主线程上似乎没有任何东西等待锁定或执行完成。
我是否将其设置为完整的bozo?这里发生了什么,我该如何解决?
答案 0 :(得分:0)
编辑:
原来所有这些网络东西都是红鲱鱼。这是一些循环的CAAnimations阻止以某种方式返回跳板。
原始猜测:
我的猜测:您不应该在启动方法中调用CFRunLoopRun
;期望并发操作的start方法在操作完成之前返回并在稍后完成。你可能正在坚持一些系统需要调度其他任务的GCD锁(线程?)。
如果您需要通过CFRunLoopRun
独占线程,您应该在start
中启动自己的线程,然后返回。我认为这样做会更容易,只是不使用NSOperation并从主线程中启动你的(已经是异步的)url连接,在每个连接完成时保留一组内容。
实际上,我认为问题是CFRunLoopStop(CFRunLoopGetCurrent())
:你在主线程上运行它,所以你要停止主运行循环!