NSOperationQueue 和 dealloc 被调用以及应用程序崩溃的问题
我在队列中创建了一个 NSOperation,如下所示:
ImageLoadingOperation *operation = [[ImageLoadingOperation alloc] initWithImageURL:url target:self action:@selector(didFinishLoadingImageWithResult:)];
[operationQueue addOperation:operation];
[operation release];
这工作正常,但如果在操作完成之前弹出视图,应用程序会因“EXC_BAD_ACCESS”而崩溃
我尝试通过调用 cancelAllOperations 来取消操作队列,但因为它已经在此过程中,它不会阻止应用程序崩溃。 docos 说,如果操作正在运行,则由操作来检测它是否已被取消并做出适当的响应,但不太确定我将如何实现这一点?
有什么想法吗?
I've created an NSOperation in the queue like so:
ImageLoadingOperation *operation = [[ImageLoadingOperation alloc] initWithImageURL:url target:self action:@selector(didFinishLoadingImageWithResult:)];
[operationQueue addOperation:operation];
[operation release];
And this works fine but if the view gets popped before the operation finishes the App crashes with "EXC_BAD_ACCESS"
I've tried to cancel the the operation Queue by calling cancelAllOperations but as its already in process it doesn't prevent the App from crashing. The docos say that if the operation is running it is up to the operation to detect that it has been canceled and respond appropriately but not too sure how I would implement this?
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以在调用操作回调之前保留视图,如上面 vodkhang 提到的。但这会不必要地延长视图的寿命,因为自从视图被弹出后,您不希望操作再继续。
下面是一个关于如何响应取消命令的草图:
该草图基于 ASIHTTPRequest 网络库,并且
有一个 关于如何响应取消命令的官方指南。
You could retain the view before the callback of operation is called, as vodkhang mentioned above. But that will prolong the life of the view unnecessarily because since the view is popped you don't want the operation to continue any more.
Here is a sketch about what you should do to respond to the cancel command:
This sketch is based on ASIHTTPRequest networking library, and
there is an official guide on how you should respond to cancel command.
您必须重写 ImageLoadingOperation 类中的“取消”操作,或者让 ImageLoadingOperation 将自身作为 KVO 观察者添加到“cancelled”属性中。在那里 - 你可以智能地取消你的操作,这样它就不会崩溃。
另外,如果您的 ImageLoadingOperation 在后台运行,那么明智的做法是以某种方式将对视图的访问推迟到主线程(所有绘图都在主线程中进行)。您可以使用dispatch_sync(dispatch_get_main_queue(), ^{});甚至执行SelectorOnMainThread来实际访问相关视图。
您会看到 - 使用操作队列的全部目的是消除依赖关系,并让事物并行运行,但是您的操作必须与视图系统更改同步,并且必须为完整性和鲁棒性而设计。
You will have to either override the "cancel" operation in your ImageLoadingOperation class, or have your ImageLoadingOperation add itself as KVO observer to the "cancelled" property. There - you can intelligently cancel your operation in such way that it won't crash.
Also, if your ImageLoadingOperation runs in the background, it would be wiser to defer your access to the views somehow to the main thread (where all drawing takes place). You could use a dispatch_sync(dispatch_get_main_queue(), ^{}); or even performSelectorOnMainThread for actual access to the related view.
You see - the whole point of using an operation queue is to remove dependencies, and let things run in parallel, but your operation must synchronize with the view-system changes, and that must be designed for completeness and robustness.
View调用一些网络然后回调是一个普遍的问题。
我的解决方案是您可以在调用操作之前保留视图。然后,当操作完成时,您释放视图。
It is a general problem for View calling some network and then callback.
My solution is you can retain the view before you call the operation. And then, when the operation finishes, you release the view.