-
Notifications
You must be signed in to change notification settings - Fork 0
iOS Notes
Dogahe edited this page Nov 22, 2021
·
15 revisions
In this wiki, I summarize some useful iOS related topics. Some of them will have links to code samples as well.
Here are some important excerpts from Apple documentation located at: link
- Whereas dispatch queues always execute tasks in first-in, first-out order, operation queues take other factors into account when determining the execution order of tasks. Primary among these factors is whether a given task depends on the completion of other tasks. You configure dependencies when defining your tasks and can use them to create complex execution-order graphs for your tasks.
- Here is a sample code that shows how to create
BlockOperation
s and create dependency between them and how to useOperationQueue
to execute theseBlockOperation
s: code
- Here is a sample code that shows how to create
- If you implemented your tasks using blocks, you can add your blocks to either a serial or concurrent dispatch queue. If a specific order is required, you would always add your blocks to a serial dispatch queue. If a specific order is not required, you can add the blocks to a concurrent dispatch queue or add them to several different dispatch queues, depending on your needs.
- If you implemented your tasks using operation objects, the choice of queue is often less interesting than the configuration of your objects. To perform operation objects serially, you must configure dependencies between the related objects. Dependencies prevent one operation from executing until the objects on which it depends have finished their work.
- Avoid using locks: The support provided by dispatch queues and operation queues makes locks unnecessary in most situations. Instead of using locks to protect some shared resource, designate a serial queue (or use operation object dependencies) to execute tasks in the correct order.
- Here is a code example for implementing a Bank ATM to prevent race condition using different methods:
- [code] (https://github.com/dogahe/swift/blob/428a81d269f131b0bd4b73cf2cd00e33f8f1f2e0/BankATMProject/BankATMProject/ViewController.swift)
- Lock: Using locks has the danger of creating a deadlock condition.
let lock = NSLock(); lock.lock(); lock.unlock()
- Using Serial Queue:
let serialQueue = DispatchQueue(label: "Serial Queue") // custom dispatch queues are serial by default
- Using Concurrent Queue with Barrier flag:
let concurrentQueue = DispatchQueue(label: "Concurrent Queue", attributes: .concurrent); concurrentQueue.async(flags: .barrier)
- Notes from Apple Documentation: Document
- Reference counting applies only to instances of classes. Structures and enumerations are value types, not reference types, and aren’t stored and passed by reference.
- To make sure that instances don’t disappear while they’re still needed, ARC tracks how many properties, constants, and variables are currently referring to each class instance. ARC will not deallocate an instance as long as at least one active reference to that instance still exists.
- Strong References: To make ARC possible, whenever you assign a class instance to a property, constant, or variable, that property, constant, or variable makes a strong reference to the instance. The reference is called a “strong” reference because it keeps a firm hold on that instance, and doesn’t allow it to be deallocated for as long as that strong reference remains.
- Weak References: A weak reference is a reference that doesn’t keep a strong hold on the instance it refers to, and so doesn’t stop ARC from disposing of the referenced instance. This behavior prevents the reference from becoming part of a strong reference cycle. You indicate a weak reference by placing the weak keyword before a property or variable declaration. Because a weak reference doesn’t keep a strong hold on the instance it refers to, it’s possible for that instance to be deallocated while the weak reference is still referring to it. Therefore, ARC automatically sets a weak reference to nil when the instance that it refers to is deallocated. And, because weak references need to allow their value to be changed to nil at runtime, they’re always declared as variables, rather than constants, of an optional type.
- Unowned References: Like a weak reference, an unowned reference doesn’t keep a strong hold on the instance it refers to. Unlike a weak reference, however, an unowned reference is used when the other instance has the same lifetime or a longer lifetime. You indicate an unowned reference by placing the unowned keyword before a property or variable declaration. Unlike a weak reference, an unowned reference is expected to always have a value. As a result, marking a value as unowned doesn’t make it optional, and ARC never sets an unowned reference’s value to nil.
- Here is a sample code that reviews these concepts: code
- Explanation on why delegates are defined as weak references: [link]