近期将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