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

我们都知道默认情况下, 因分类底层结构的限制,  是不能添加成员变量到分类中. 但可以利用runtime 关联对象来间接实现.

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

给AppDelegate写一个分类, 目的是监听 AppDelegate 在前台还是后台.

#import "AppDelegate.h"

#import  

@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张图片
1.png

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

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

你可能感兴趣的:(给分类间接添加成员变量及使用场景)