Skip to content

Instantly share code, notes, and snippets.

@SheldonWangRJT
Last active August 5, 2018 04:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SheldonWangRJT/d7415a233fc1d83c3af2182304243019 to your computer and use it in GitHub Desktop.
Save SheldonWangRJT/d7415a233fc1d83c3af2182304243019 to your computer and use it in GitHub Desktop.
How Does Apple Realize KVO?

How Does Apple Realize KVO?

#iOSBySheldon

As you may all know KVO stands for key-value observing. It is a mechanism you can use to do the reactive programming. I have posted a video about how to use KVO + KVC for reactive programming here, please don't hesitate to check it out. I will give you an good example of using KVO. Suppose you have a downloading progress value coming, Float for example. You have to update your UIProgressBar with that value. A good way to achieve this might be let your UIProgressBar observe that Float value and whenever that float value changed, you change your UIProgressBar.value accordingly. Again, please feel free to check my video tutorial about that as well as the finished project here in Github.

How does Apple realize this?

Per Apple's document, "Automatic key-value observing is implemented using a technique called isa-swizzling… When an observer is registered for an attribute of an object the isa pointer of the observed object is modified, pointing to an intermediate class rather than at the true class …"

Let me explain whatever Apple told us, including what is isa-swizzling.

  1. KVO is based on iOS RunTime. I may write a separate blog about iOS RunTime itself.
  2. When we start observing a property under a Class, iOS when dynamically create a Class to "replace" the original Class. The new Class will override the setter of that property you are observing. Therefore, the newly created Class is the "real" one to handle KVO.
  3. For example, if you have a Class called People, the new Class will be NSKVONotifying_People.
  4. Assuming you have an instance of People, let tom = People(), when you create tom, tom will have an isa pointer point to People, but if you implement KVO in People, now that isa pointer will point to NSKVONotifying_People. This process is called isa-swizzling, which is mentioned in the Apple document paragraph. Please check the isa-pointer graph below.
  5. With all above being said, we know we will be notified when observed property's value is changed. Actually, we will be notified through few delegate functions. These delegate functions is part of NSCoding Protocol. So you have to make your Class confirm to NSCoding Protocol to make this work. A good thing is that NSObject by default is already confirming to NSCoding, so any Class that sub-classing NSObject will have this for free. The two most useful delegates functions are willChangeValueForKey() & didChangeValueForKey().

References:
[1] https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html
[2] https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Introduction/Introduction.html
[3] https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/ObjectCreation.html
[4] https://github.com/SheldonWangRJT/iOS-KVO-KVC
[5] https://www.youtube.com/watch?v=xS7bvtGPiuU

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment