Recently, xcode was upgraded to 4.2, And the SDK is ios5. In iOS 5, nsoperation that previously worked normally will crash. The cause of the crash is that the operation in the queue is canceled, but the operation has not started yet.
The solution to this problem is:
In the start method, determine whether the operation has been canceled. If the operation is canceled, stop the operation. If the operation is not canceled, perform the operation again.
In the cancel method, determine whether the operation is being executed. If the operation is being executed, end the operation. If not, modify the iscancelled status of the operation.
Header file:
# Import <Foundation/Foundation. h> </P> <p> @ interface fmurlrequest: nsoperation {</P> <p> bool _ isready; <br/> bool _ iscancelled; <br/> bool _ isexecuting; <br/> bool _ isfinished; <br/>}</P> <p>-(void) Cancel; </P> <p> @ end <br/>
Implementation file:
# Import "fmurlrequest. H "</P> <p> @ interface fmurlrequest () </P> <p>-(bool) isready; <br/>-(bool) isexecuting; <br/>-(bool) isfinished; <br/>-(bool) iscancelled; <br/>-(bool) isconcurrent; </P> <p>-(void) Start; <br/>-(void) finish; </P> <p> @ end </P> <p> @ implementation fmurlrequest </P> <p>-(ID) init {</P> <p> If (Self = [Super init]) {<br/> _ iscancelled = no; <br/> _ isexecuting = no; <br/> _ isfinished = no; <Br/> _ isready = yes; <br/>}</P> <p> return self; <br/>}</P> <p>-(void) dealloc {</P> <p> [Super dealloc]; <br/>}</P> <p> # pragma-<br/> # pragma mark Operation Management & super class methods </P> <p>-(bool) isready {</P> <p> return _ isready; <br/>}</P> <p>-(bool) isexecuting {</P> <p> return _ isexecuting; <br/>}</P> <p>-(bool) isfinished {</P> <p> return _ isfinished; <br/>}</P> <p>-(bool) iscancelled {</P> <P> return _ iscancelled; <br/>}</P> <p>-(bool) isconcurrent {</P> <p> return yes; <br/>}</P> <p>-(void) Start {</P> <p> If (! [Nsthread ismainthread]) {<br/> [self defined mselecw.mainthread: @ selector (start) withobject: Nil waituntildone: No]; <br/> return; <br/>}</P> <p> [self willchangevalueforkey: @ "isexecuting"]; <br/> _ isexecuting = yes; <br/> [self didchangevalueforkey: @ "isexecuting"]; </P> <p> If ([self iscancelled]) {<br/> [self finish]; <br/> return; <br/>}</P> <p> // todo: Start Operation <br/>}</P> <p>-(void) finish {</P> <p> [self willchangevalueforkey: @ "isexecuting"]; <br/> [self willchangevalueforkey: @ "isfinished"]; </P> <p> _ isexecuting = no; <br/> _ isfinished = yes; </P> <p> [self didchangevalueforkey: @ "isexecuting"]; <br/> [self didchangevalueforkey: @ "isfinished"]; <br/>}</P> <p>-(void) cancel {</P> <p> [self willchangevalueforkey: @ "iscancelled"]; <br/> _ iscancelled = yes; <br/> [self didchangevalueforkey: @ "iscancelled"]; </P> <p> If ([self isexecuting] = Yes) {<br/> // todo: clean resource <br/> [self finish]; <br/>}</P> <p> @ end <br/>