简体   繁体   中英

Swift Completion Block

I want to achieve the following :

  1. In classB, to reload my database after adding 1 object. reloadDatabase() is called within the completionBlock.
  2. In classB, reloadDatabase() will call getObjects() in classA to get the most updated list of database objects and pass to objectList in classB

Question: How do i ensure that whenever i call getObjectList() in classB, i will always get the most updated list? From my understanding, my objectList might not be update in reloadDatabase() block . I could be calling getObjectList() when reloadDatabase() haven't reach the completion block yet (objectList is still the old objectList).

I am pretty new to closures and blocks. Any guidance is greatly appreciated!

    class classA: NSObject { 
      func addThisObject(object: RLMObject, completionBlock: () -> ())){

        ...
        completionBlock()
      } 


      func getObjects (completionBlock: ((list: [RLMObject]) -> ())){

        var recordList = [RLMObject]()
        ...
        completionBlock(list: recordList)
      }
    }


    class classB: NSObject { 

      var objectList = [RLMObject]()

      func addObject (object: RLMObject) {

        classA().addThisObject(object, completionBlock: {() -> () in
          self.reloadDatabase()
        }) 

      }

     func reloadDatabase() {

       classA().getObjects{(list) -> () in 
         self.objectList = list 
       }
    }

     func getObjectList() -> [RLMObject] {
       return objectList 
     }
    }

In your question, you don't say whether you'll be calling any of these functions from different threads. So when you call addObject() in classB, execution wouldn't even continue until the database has been reloaded and objectList was updated.

Using closures and blocks does not automatically imply that code will be executed on a different context.

From your snippets it seems to me there is no asynchronous calls, so you won't be able to call getObjectList() before reloadDatabase() block. Closures are not asynchronous if you don't use them with something that is (eg GCD).

If you have asynchronous calls, but they are not in the snippets, then getObjectList() can be called while reloadDatabase() is being executed. Then you have few options:

  • Remove asynchronous calls
  • Use serial queue for your methods
  • Add boolean variable updateInProgress and check it in getObjectList() - how to do it
  • Ignore the fact that data may be outdated - it is correctness vs speed trade.
  • Let your database inform its clients that something changed

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM