ios - Executing the NSOperation when all other operations in NSOperationQueue finished no matter whether they finished successfully or not -


hi have strange situation here :

overview:

i working on app user can initiate multiple operations , these operations run on background thread hence not block ui. of these operations dependent on each other , not. in order ensure operation execute after necessary dependencies operations finished executing using dependency property of operation. making use of asynchronous operations.

here implementation :

import uikit import coredata import swiftyjson  class vmbaseoperation: nsoperation {     var finishedstatus : bool = false     var executionstatus : bool = false     var retrycount : int = 0     private (set) var requesttoqueue : baserequest? = nil     var vmoperationcompletionblock: ((json?) -> void)?     var vmoperationfailureblock: ((webresponseerror?) -> void)?      override init() {         super.init()     }      convenience init(withvmrequest request : baserequest) {         self.init()         requesttoqueue = request     }      override func start() {         if self.cancelled {             self.finished = true             return         }         nsthread.detachnewthreadselector(#selector(main), totarget: self, withobject: nil)         self.executionstatus = true     }       override func main() {         if self.cancelled {             return         }         self.hitwebservice()     }      func hitwebservice(){         let webservicemanager = webservicemanager()         webservicemanager.getresponsefromrequest(requesttoqueue!) { (requset, response, data, error) in             let error = webresponseerror.checkresponse(response, request: requset, error: error)             if error != nil {                 if error == webresponseerror.no_internet {                     if self.vmoperationfailureblock != nil {                         self.vmoperationfailureblock!(error)                     }                     self.operationfailed()                 }                 else{                     self.retrycount += 1                     if self.retrycount == 3 {                         if self.vmoperationfailureblock != nil {                             self.vmoperationfailureblock!(error)                         }                         self.operationfailed()                     }                     else{                         self.hitwebservice()                     }                 }             }             else{                 if data == nil {                     self.retrycount += 1                     if self.retrycount == 3 {                         if self.vmoperationfailureblock != nil {                             self.vmoperationfailureblock!(nil)                         }                         self.operationfailed()                     }                     else{                         self.hitwebservice()                     }                 }                 else{                     let json = json(data: data!)                     if self.vmoperationcompletionblock != nil {                         self.vmoperationcompletionblock!(json)                     }                     self.operationcompleted()                 }             }         }     }      override var finished: bool {         get{             return finishedstatus         }         set{             self.willchangevalueforkey("isfinished")             finishedstatus = newvalue             self.didchangevalueforkey("isfinished")         }     }      override var executing: bool {         get{             return executionstatus         }         set{             self.willchangevalueforkey("isexecuting")             executionstatus = newvalue             self.didchangevalueforkey("isexecuting")         }     }       override var asynchronous: bool{         get{             return true         }         set{             self.willchangevalueforkey("isasynchronous")             self.asynchronous = true             self.didchangevalueforkey("isasynchronous")         }     }      func operationcompleted(){         self.executing = false         self.finished = true     }      func operationfailed(){         self.executing = false         self.finished = false     } } 

what :

each operation takes web request , attempts data server , if fails, tries 3 times before setting finished status false calling operationfailed method , there stopping dependent operation executing forever.on other hand if succeeds changes finished status true calling operationcompleted hence triggers execution of remaining dependent operations.

what issue:

dependency works charm. no issue that. need sync data server when operations in operation queue finished executing no matter whether finished or not.

easiest way create operation sync data server , add dependent operation operations added operationqueue.

but because of above mentioned nature of operation, if 1 operation fails stops execution of dependent operations (as expected) because sync data server operation dependent operation never execute if 1 operation fails :(

what need :

while maintaining dependency mentioned above need know how execute operation sync data server when operations in operation queue finishes executing no matter whether succeed or fail.

is possible :( please me out . in advance.

with implementation operationfailed:

func operationfailed(){     self.executing = false     self.finished = false } 

you break nsoperation's native logic:

operation dependencies

dependencies convenient way execute operations in specific order. can add , remove dependencies operation using adddependency: , removedependency: methods. default, operation object has dependencies not considered ready until of dependent operation objects have finished executing. once last dependent operation finishes, however, operation object becomes ready , able execute.

the dependencies supported nsoperation make no distinction whether dependent operation finished or unsuccessfully. (in other words, canceling operation marks finished.) it determine whether operation with dependencies should proceed in cases dependent operations were cancelled or did not complete task successfully. may require incorporate additional error tracking capabilities operation objects.

by design if operation fails should finish. mark somehow (some special property or cancelled one).

dependent operations should check possible start. following should job:

var requiredependencescompletion: bool = true  override var ready: bool {      if requiredependencescompletion     {         op in self.dependencies {             if op.cancelled {                 cancel()         }     }     super.ready } 

here override ready property determine should done. if requiredependencescompletion true operation check dependences , cancel if 1 of them cancelled.

set requiredependencescompletion true typical operations , false barrier operation start in case.


Comments

Popular posts from this blog

amazon web services - S3 Pre-signed POST validate file type? -

c# - Check Keyboard Input Winforms -