iOS - runtime

作者: Bruce_XHG | 来源:发表于2017-04-27 23:15 被阅读0次

runtime 在开发过程中使用的地方还是很多的。比如交换系统方法和自己的方法,达到实现自己方法内部的一些特殊实现,;比如通过runtime 动态给分类添加属性;比如获取当前类的所有成员变量,属性和方法。这些都是 runtime 能给我们提供的黑科技。
runtime 从下面几点开始讲解:

  • runtime 获取类的属性列表

  • runtime 获取类的成员变量列表

  • runtime 获取类的方法列表

  • runtime 交换两个方法

  • runtime 添加属性

  • 1、runtime 获取当前类的属性列表

unsigned int 类似于 NSUInteger 无符号整形

unsigned int count;
    objc_property_t *propertyList = class_copyPropertyList([self class], &count);
    for (unsigned int i = 0; i < count; i++) {
        const char *propertyName = property_getName(propertyList[i]);
        DebugLog(@"-----getRunTimePropertyList: %@",[NSString stringWithUTF8String:

得到当前类的属性##

RunTimeLearnViewController.m:52 
-----getRunTimePropertyList: testArry

现实证明是正确的,我申明了一个testArry的数组,通过 runtime 获取的当前类属性列表就是testArry。#

  • 2、获取成员变量列表
unsigned int count;
    Ivar *ivarList = class_copyIvarList([self class], &count);
    for (unsigned int i = 0; i < count; i++) {
        Ivar ivar = ivarList[i];
        DebugLog(@"-------getRunTimeIvarList: %@",[NSString stringWithUTF8String:ivar_getName(ivar)]);
    }

得到当前类的成员变量##

-------getRunTimeIvarList: _testArry

我们都知道,iOS 会根据申明的属性自动的生成对应的成员变量。我们申明了一个testArry数组属性,所以也就对应自动生成了一个_testArry成员变量。#

  • 3、获取类的方法列表
unsigned int count;
    Method *methodList = class_copyMethodList([self class], &count);
    for (int i = 0; i < count; i++) {
        Method method = methodList[i];
        DebugLog(@"------getRunTimeMethodList: %@",NSStringFromSelector(method_getName(method)));
    }

得到当前类的方法##

------getRunTimeMethodList: logOne
RunTimeLearnViewController.m:62 
------getRunTimeMethodList: logTwo
RunTimeLearnViewController.m:62 
------getRunTimeMethodList: getRunTimePropertyList
RunTimeLearnViewController.m:62 
------getRunTimeMethodList: getRunTimeMethodList
RunTimeLearnViewController.m:62 
------getRunTimeMethodList: getRunTimeIvarList
RunTimeLearnViewController.m:62 
------getRunTimeMethodList: testArry
RunTimeLearnViewController.m:62 
------getRunTimeMethodList: setTestArry:
RunTimeLearnViewController.m:62 
------getRunTimeMethodList: didReceiveMemoryWarning
RunTimeLearnViewController.m:62 
------getRunTimeMethodList: viewWillAppear:
RunTimeLearnViewController.m:62 
------getRunTimeMethodList: viewDidLoad
RunTimeLearnViewController.m:62 
------getRunTimeMethodList: .cxx_destruct

cxx_destruct:http://www.cocoachina.com/ios/20140604/8669.html

  • 4、runtime 交换两个方法

cell的分类,全局设置分割线顶头#

+(void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
        SEL originalSelector = @selector(layoutSubviews);
        SEL swizzledSelector = @selector(swizzling_layoutSubviews);
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        method_exchangeImplementations(originalMethod, swizzledMethod);
    });
}
-(void)swizzling_layoutSubviews{
    [self swizzling_layoutSubviews];
    //获取成员变量列表
//    unsigned int count;
//    Ivar *ivarList = class_copyIvarList([self class], &count);
//    for (unsigned int i = 0; i < count; i++) {
//        Ivar ivar = ivarList[i];
//        DebugLog(@"-------getRunTimeIvarList: %@",[NSString stringWithUTF8String:ivar_getName(ivar)]);
//    }
    UIView *separatorView = [self valueForKey:@"_separatorView"];
    CGRect frame = separatorView.frame;
    frame.origin.x = 0;
    frame.size.width = self.frame.size.width;
    separatorView.frame = frame;
}
  • 5、runtime 添加属性
@interface UITextField (MYAdd)
@property (nonatomic, assign) NSUInteger maxLength;
@property (nonatomic, strong) UIFont *placeholderFont;
@property (nonatomic, strong) UIColor *placeholderColor;
@end
static char *const KTextFieldTextMaxLength = "TextFieldTextMaxLength";
static char *const KTextFieldPlaceholderFont = "TextFieldPlaceholderFont";
static char *const KTextFieldPlaceholderColor = "TextFieldPlaceholderColor";
-(NSUInteger)maxLength {
    NSNumber *maxLengthNum = objc_getAssociatedObject(self, KTextFieldTextMaxLength);
    if (!maxLengthNum) {
        return NSUIntegerMax;
    }
    return [maxLengthNum unsignedIntegerValue];
}
-(void)setMaxLength:(NSUInteger)maxLength {
    objc_setAssociatedObject(self, KTextFieldTextMaxLength, @(maxLength), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(UIFont *)placeholderFont {
    return objc_getAssociatedObject(self, KTextFieldPlaceholderFont);
}
-(void)setPlaceholderFont:(UIFont *)placeholderFont {
    objc_setAssociatedObject(self, KTextFieldPlaceholderFont, placeholderFont, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self setPlaceholder:self.placeholder];
}
-(UIColor *)placeholderColor {
    return objc_getAssociatedObject(self, KTextFieldPlaceholderColor);
}
-(void)setPlaceholderColor:(UIColor *)placeholderColor {
    objc_setAssociatedObject(self, KTextFieldPlaceholderColor, placeholderColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self setPlaceholder:self.placeholder];
}

相关文章

网友评论

    本文标题:iOS - runtime

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