Runtime的用法(上):给category 添加属性 和方法交换

很长时间都没有静下心来写博客了。

  这半年,原生iOS基本上没有开发任务,都是一些无关紧要的迭代。大部分开发时间放在了前端angular项目上,现在的前端水平也仅仅是,依葫芦画瓢,刚好完成开发任务而已。iOS的基础东西虽然说没有丢,但是一直没有往更深的方向去专研,Swift也是刚好会用,没有深究。温水煮青蛙,和刚进公司的那一会比,心态差距很大。今天把一些基础性的东西runtime,重拾一下吧。

  • runtime 给category 添加属性

category和继承,有相似的功能。继承既能添加方法,也能添加成员变量。继承是子类继承自父类,子类中增加的方法不会成为父类的一部分。category可以在不知道类源码的情况下,为类添加新方法,不能添加成员变量,但是可以用过runtime来实现。以前项目中很多通用的属性都用继承实现,但是不太好维护(安慰自己罢了☺,两年了,一直都是自己一个人维护项目),改成category来实现。

#import <UIKit/UIKit.h>

@interface UIViewController (Extension)

@property (nonatomic,copy) NSString * fileName;

@end
#import "UIViewController+Extension.h"

#import <objc/runtime.h>

@implementation UIViewController (Extension)

//getter
- (void)setFileName:(NSString *)fileName
{
    objc_setAssociatedObject(self, @selector(fileName), fileName, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

//setter
- (NSString *)fileName
{
    NSString * _fileName = objc_getAssociatedObject(self, @selector(fileName));
    if (!_fileName)
    {
        _fileName = @"xx.mp3";
        objc_setAssociatedObject(self, @selector(fileName), _fileName, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return _fileName;
}
  • runtime 来替换方法

这个其实很多地方都用到了,比如用NullSafe来避免遇到null崩溃等。

+ (void)load
{
    //类加载时调用,确保只执行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //原始方法 这里只是举例,viewWillAppear
        Method originalM = class_getClassMethod([self class], @selector(viewWillAppear:));
        
        //自定义方法
        Method customM = class_getClassMethod(self, @selector(yy_viewVillAppear:));
        
        //交换
        method_exchangeImplementations(originalM, customM);
        
    });
}

- (void)yy_viewVillAppear:(BOOL)animated
{
    NSLog(@"%s",__FUNCTION__);
    
    //这里已经替换了方法viewWillAppear,所以不是递归调用
    [self yy_viewVillAppear:animated];
}

下篇的传送门Runtime的用法(下):给Model赋值

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容