美文网首页
给分类间接添加成员变量及使用场景

给分类间接添加成员变量及使用场景

作者: Jason_风筝 | 来源:发表于2018-11-01 09:57 被阅读0次
    我们都知道默认情况下, 因分类底层结构的限制,  是不能添加成员变量到分类中. 但可以利用runtime 关联对象来间接实现.
    

    下面我们来写一个分类, 关联一个属性, 及使用. 其实说到底, 关联一个属性就是为了方便调用.

    给AppDelegate写一个分类, 目的是监听 AppDelegate 在前台还是后台.
    
    
    #import "AppDelegate.h"
    
    #import  <objc/runtime.h>
    
    @interfaceAppDelegate (Push)
    
    /// 生成setter/getter 声明
    
    @property(nonatomic,strong) NSNumber* applicationInBackground;
    
    @end
    
    @implementation AppDelegate (Push)
    
    // 利用runtime 交换方法
    
    + (void)load {
    
        Method original =class_getInstanceMethod(self,@selector(application:didFinishLaunchingWithOptions:));
    
        Method swizzled =class_getInstanceMethod(self,@selector(application:swizzledDidFinishLaunchingWithOptions:));
    
        method_exchangeImplementations(original, swizzled);
    
    }
    
    ///实现set 方法
    
    // 参数1: 要给谁关联对象     
    
    // 参数2: 储存值对应的key ,因为它底层也key-value 的形式存值的. 这里说一下这个key, 因为get时是根据key get value. 所以比较好的做法可以把 @selector(applicationInBackground) 储存地址当key     
    
    // 参数3: 储存值     
    
    // 参数4: 相当于property中的类型, 对象类型Strong , 基本类型用 assign, 注意里面的宏.     
    
    //objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,  id _Nullable value, objc_AssociationPolicy policy)
    
    - (void)setApplicationInBackground:(NSNumber *)applicationInBackground {     
    
        objc_setAssociatedObject(self, @selector(applicationInBackground), applicationInBackground, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
    
    }
    
    /// 实现get 方法 
    
    - (NSNumber*)applicationInBackground {
    
        /// 注意保持key 相同
    
        return objc_getAssociatedObject(self,@selector(applicationInBackground));
    
    }
    
    
    
    - (BOOL)application:(UIApplication*)application swizzledDidFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
    
        // 调用原始的方法
    
        [self application:application swizzledDidFinishLaunchingWithOptions:launchOptions];
    
        // 给属性赋值
    
        self.applicationInBackground = @(YES);
    
        return YES;
    
    }
    
    - (void)applicationDidBecomeActive:(UIApplication*)application {
    
        self.applicationInBackground = @(NO);
    
    }
    
    - (void)applicationDidEnterBackground:(UIApplication*)application {
    
        self.applicationInBackground = @(YES);
    
    }
    

    // 赋张类型修饰选择图


    1.png

    到此, 外界只要导入它, 根据 applicationInBackground 就可以知道是在前台还是在后台.

    这就是给分类关联一个属性的简便使用.

    相关文章

      网友评论

          本文标题:给分类间接添加成员变量及使用场景

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