NSOperation & Queue 的用法和注意事項(xiàng)都比較清楚
從官方文檔來武裝一下自己(游擊隊(duì)->正規(guī)軍)
記錄一些自己感覺從官方文檔中看到的比較有意義的點(diǎn)
基礎(chǔ)知識就不再記錄了
The NSOperationQueue class regulates the execution of a set of NSOperation objects. After being added to a queue, an operation remains in that queue until it is explicitly canceled or finishes executing its task. Operations within the queue (but not yet executing) are themselves organized according to priority levels and inter-operation object dependencies and are executed accordingly. An application may create multiple operation queues and submit operations to any of them.
- operation queue
- queue 是管理 operation 集合的對象(管理者)
- operation 被添加到 queue 后,一直被管理,知道他 cancel finished
- operation 被管理根據(jù)其 priority levels 和 dependencies
- queue 可以有多個
If you plan on executing an operation object manually, instead of adding it to a queue, you can design your operation to execute in a synchronous or asynchronous manner. Operation objects are synchronous by default. In a synchronous operation, the operation object does not create a separate thread on which to run its task. When you call the start method of a synchronous operation directly from your code, the operation executes immediately in the current thread. By the time the start method of such an object returns control to the caller, the task itself is complete.
- NSOperation 可以設(shè)計(jì)為 異步 同步。
- 默認(rèn)同步執(zhí)行
- 代碼代用 start 方法時,當(dāng) main 方法執(zhí)行完后,operation complete
When you call the start method of an asynchronous operation, that method may return before the corresponding task is completed. An asynchronous operation object is responsible for scheduling its task on a separate thread. The operation could do that by starting a new thread directly, by calling an asynchronous method, or by submitting a block to a dispatch queue for execution. It does not actually matter if the operation is ongoing when control returns to the caller, only that it could be ongoing.
- 異步operation,在 start 方法執(zhí)行完后,也可能不會 complete
- start 后,會將 operation 放到一個新的線程,或者放到一個異步方法中,或者 gcd 執(zhí)行
If you always plan to use queues to execute your operations, it is simpler to define them as synchronous. If you execute operations manually, though, you might want to define your operation objects as asynchronous. Defining an asynchronous operation requires more work, because you have to monitor the ongoing state of your task and report changes in that state using KVO notifications. But defining asynchronous operations is useful in cases where you want to ensure that a manually executed operation does not block the calling thread.
When you add an operation to an operation queue, the queue ignores the value of the asynchronous property and always calls the start method from a separate thread. Therefore, if you always run operations by adding them to an operation queue, there is no reason to make them asynchronous.
- 異步operation 比較麻煩,你需要自己維護(hù) KVO
- 如果Operation 總是在 queue 中執(zhí)行,queue 默認(rèn)會開啟新線程異步執(zhí)行,所以沒有必要再自己實(shí)現(xiàn)異步
- 但是如果真的需要有異步的情況,還是自己寫異步比較好
Operation Dependencies
Dependencies are a convenient way to execute operations in a specific order. You can add and remove dependencies for an operation using the addDependency: and removeDependency: methods. By default, an operation object that has dependencies is not considered ready until all of its dependent operation objects have finished executing. Once the last dependent operation finishes, however, the operation object becomes ready and able to execute.
- 如果一個 operation 有依賴的話,他的 ready 狀態(tài)只有在所有的依賴都 finished 才會更改為 ready
isCancelled - read-only
isAsynchronous - read-only
isExecuting - read-only
isFinished - read-only
isReady - read-only
dependencies - read-only
queuePriority - readable and writable
completionBlock - readable and writable
- 可以 KVO 的屬性
Methods to Override
For non-concurrent operations, you typically override only one method:
[main]
Into this method, you place the code needed to perform the given task. Of course, you should also define a custom initialization method to make it easier to create instances of your custom class. You might also want to define getter and setter methods to access the data from the operation. However, if you do define custom getter and setter methods, you must make sure those methods can be called safely from multiple threads.
子類實(shí)現(xiàn)的是非異步的 operation 只需要實(shí)現(xiàn) main 方法接口
如果自定義屬性 getter setter 方法,保證線程安全
If you are creating a concurrent operation, you need to override the following methods and properties at a minimum:
In a concurrent operation, your start method is responsible for starting the operation in an asynchronous manner. Whether you spawn a thread or call an asynchronous function, you do it from this method. Upon starting the operation, your start method should also update the execution state of the operation as reported by the executing property. You do this by sending out KVO notifications for the executing key path, which lets interested clients know that the operation is now running. Your executing property must also provide the status in a thread-safe manner.
Upon completion or cancellation of its task, your concurrent operation object must generate KVO notifications for both the isExecuting and isFinished key paths to mark the final change of state for your operation. (In the case of cancellation, it is still important to update the isFinished key path, even if the operation did not completely finish its task. Queued operations must report that they are finished before they can be removed from a queue.) In addition to generating KVO notifications, your overrides of the executing and finished properties should also continue to report accurate values based on the state of your operation.
如果創(chuàng)建的是異步 operation 上面幾個屬性和方法是必須實(shí)現(xiàn)的
start 方法里面,一定要更改 executing 狀態(tài) ,并且 KVO 通知,保證線程安全
complete or cancel 后,一定要更改 executing finished 狀態(tài) ,并且 KVO 通知,保證線程安全
At no time in your start method should you ever call super
- start 方法里面,不應(yīng)該調(diào)用父類的 start 方法