有很多公司iOS面試都會被問到KVO底層的實現(xiàn)放椰。網(wǎng)上也有很多篇關(guān)于KVO的底層原理忱详,但是都是用willChangeValueForKey 和 didChangeValueForKey 來實現(xiàn)的KVO浑玛。最近從網(wǎng)上公開課學到用runtime底層機制自己實現(xiàn)了一個KVO,接下來就進入正題凿歼。?
1划鸽、注冊一個類,屬于當前的的子類
NSString * selfClassStr =NSStringFromClass([selfclass]);
NSString * subClassStr = [@"KVO_" stringByAppendingString:selfClassStr];
Classsub Class =objc_allocateClassPair([selfclass], subClassStr.UTF8String,0);
objc_registerClassPair(subClass);//特別注意生成類之后需要注冊弦赖。
2项栏、把當前類的指向子類
object_setClass(self, subClass);
3、給子類添加set方法
NSString* capitalizedKeyPath = [keyPathcapitalizedString];
NSString* methodNameStr = [NSString stringWithFormat:@"set%@:",capitalizedKeyPath];
class_addMethod(subClass,NSSelectorFromString(methodNameStr), (IMP)observerBlock,"");
4蹬竖、儲存observer對象
objc_setAssociatedObject(self,@"key", observer,OBJC_ASSOCIATION_ASSIGN);
5沼沈、實現(xiàn)添加方法里面的observerBlock方法
Class class = [self class];
object_setClass(self, [self superclass]);
id observer =objc_getAssociatedObject(self,@"observer");
objc_msgSend(self,@selector(setName:),name);
objc_msgSend(observer,@selector(observeValueForKeyPath:ofObject:change:context:),@"name",self,@{@"newValue":name},nil);
object_setClass(self, class);
附二張圖
差不多到這里runtime實現(xiàn)KVO已經(jīng)初步完成。里面有很多API沒有細講币厕,只是把KVOdidChangeValueForKey實現(xiàn)列另。有興趣的小伙伴可以交流交流。
第一次在網(wǎng)絡(luò)上發(fā)干貨旦装,哈哈页衙。不喜勿噴。 以后也會常發(fā),為了鞏固自己的技術(shù)店乐,也和大家多分享一些干貨艰躺,以后面試不再怕啦!U0恕腺兴!
最后GitHub 地址:?KVO