近期将xcode升级到了4.2,SDK是 iOS5。在 iOS 5 下,以前可以正常工作的 NSOperation,会崩溃。崩溃的原因是:取消队列中的操作,但是该操作还没有开始。
解决这个问题的方法是:
在 start 方法中判断操作是否已经取消,如果取消,结束操作,没有取消,再执行操作。
在 cancel 方法中判断操作是否正在执行,如果在执行,结束操作,如果没有,修改操作的isCancelled状态。
头文件:
#import <Foundation/Foundation.h> @interface FMURLRequest : NSOperation { BOOL _isReady; BOOL _isCancelled; BOOL _isExecuting; BOOL _isFinished; } - (void)cancel; @end
实现文件:
#import "FMURLRequest.h" @interface FMURLRequest () - (BOOL)isReady; - (BOOL)isExecuting; - (BOOL)isFinished; - (BOOL)isCancelled; - (BOOL)isConcurrent; - (void)start; - (void)finish; @end @implementation FMURLRequest - (id)init { if ((self = [super init])) { _isCancelled = NO; _isExecuting = NO; _isFinished = NO; _isReady = YES; } return self; } - (void)dealloc { [super dealloc]; } #pragma - #pragma mark Operation Management & Super Class Methods - (BOOL)isReady { return _isReady; } - (BOOL)isExecuting { return _isExecuting; } - (BOOL)isFinished { return _isFinished; } - (BOOL)isCancelled { return _isCancelled; } - (BOOL)isConcurrent { return YES; } - (void)start { if (![NSThread isMainThread]) { [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO]; return; } [self willChangeValueForKey:@"isExecuting"]; _isExecuting = YES; [self didChangeValueForKey:@"isExecuting"]; if ([self isCancelled]) { [self finish]; return; } // TODO: start operation } - (void)finish { [self willChangeValueForKey:@"isExecuting"]; [self willChangeValueForKey:@"isFinished"]; _isExecuting = NO; _isFinished = YES; [self didChangeValueForKey:@"isExecuting"]; [self didChangeValueForKey:@"isFinished"]; } - (void)cancel { [self willChangeValueForKey:@"isCancelled"]; _isCancelled = YES; [self didChangeValueForKey:@"isCancelled"]; if ([self isExecuting] == YES) { // TODO: clean resource [self finish]; } } @end