美文网首页
ISA Swizzling 《iOS编程实战》

ISA Swizzling 《iOS编程实战》

作者: iChanne | 来源:发表于2016-09-04 00:15 被阅读647次

    《iOS编程实战》24.6节
    方法混写和ISA混写的区别
    KVO是通过ISA混写实现的,这样系统框架就可以在我们的类中注入通知代码,一如把代码注入系统框架。
    ISA混写是修改某一个特定对象的类,不会影响这个类的其他对象。
    修改对象的类为自定义的类后,自定义类中的方法就能执行,我们可以在这些方法中添加我们想要的功能。当然,这些方法都存在于修改前的类中,所以自定义类都是修改前类的子类。

    NSObject+SetClass.h

    #import <Foundation/Foundation.h>
    @interface NSObject (SetClass)
    - (void)setClass:(Class)aClass;
    @end
    

    NSObject+SetClass.m

    #import "NSObject+SetClass.h"
    #import <objc/runtime.h>
    @implementation NSObject (SetClass)
    - (void)setClass:(Class)aClass {
        //确保两个类大小一样,也就是说aClass不能声明任何 ivar 或者合成属性 
        NSAssert(class_getInstanceSize([self class]) == class_getInstanceSize(aClass), @"Classes must be the same size to swizzle.");
    
        //设置一个对象的类,这里改变 self 的类为 aClass
        //Class object_setClass(id object, Class cls)
        object_setClass(self, aClass);}
    @end
    

    MYNotificationCenter.h

    #import <Foundation/Foundation.h>
    @interface MYNotificationCenter : NSNotificationCenter    
    // 这里绝对不要定义任何实例变量 ivar 或者合成属性
    @end
    

    MYNotificationCenter.m

    #import "MYNotificationCenter.h"
    @implementation MYNotificationCenter
    
    - (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject
    {
       // 添加的代码
        NSLog(@"Adding observer: %@", observer);
       //  调用自定义类的父类方法,保证原来功能不缺失
       [super addObserver:observer selector:aSelector name:aName
                    object:anObject];}
    @end
    

    在程序开始的某个地方执行方法混写:

    #import "NSObject+SetClass.h"
    #import "MYNotificationCenter.h"
    
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center setClass:[MYNotificationCenter class]];
    //之后,调用系统[NSNotificationCenter defaultCenter]时会自动替换会自定义的[MYNotificationCenter defaultCenter]
    
    

    相关文章

      网友评论

          本文标题:ISA Swizzling 《iOS编程实战》

          本文链接:https://www.haomeiwen.com/subject/bpllettx.html