runtime

作者: ios_stand | 来源:发表于2017-04-11 14:38 被阅读0次

一:可遍历苹果类内部的成员变量,属性,方法
例如想改变UITextField的placeholder的字体颜色

#import <UIKit/UIKit.h>

@interface XMGTextField : UITextField

@end
#import "XMGTextField.h"
#import <objc/runtime.h>

@implementation XMGTextField

+ (void)initialize
{
    [self getIvars];
}

//+ (void)getProperties
//{
//    unsigned int count = 0;
//    
//    objc_property_t *properties = class_copyPropertyList([UITextField class], &count);
//    
//    for (int i = 0; i<count; i++) {
//        // 取出属性
//        objc_property_t property = properties[i];
//        
//        // 打印属性名字
//        XMGLog(@"%s   <---->   %s", property_getName(property), property_getAttributes(property));
//    }
//    
//    free(properties);
//}

+ (void)getIvars
{
    unsigned int count = 0;
    
    // 拷贝出所有的成员变量列表
    Ivar *ivars = class_copyIvarList([UITextField class], &count);
    
    for (int i = 0; i<count; i++) {
        // 取出成员变量
        //        Ivar ivar = *(ivars + i);
        Ivar ivar = ivars[i];
        
        // 打印成员变量名字,通过打印可以发现_placeholderLabel成员变量
        XMGLog(@"%s %s", ivar_getName(ivar), ivar_getTypeEncoding(ivar));
    }
    
    // 释放
    free(ivars);
}

- (void)awakeFromNib
{
    [super awakeFromNib];
    self.textColor = [UIColor whiteColor];
    // 设置光标颜色和文字颜色一致
    self.tintColor = self.textColor;
    
    // 不成为第一响应者
    [self resignFirstResponder];
}

/**
 * 当前文本框聚焦时就会调用
 */
- (BOOL)becomeFirstResponder
{
    // 修改占位文字颜色(通过KVC访问成员变量)
    [self setValue:self.textColor forKeyPath:@"_placeholderLabel.textColor"];
    return [super becomeFirstResponder];
}

/**
 * 当前文本框失去焦点时就会调用
 */
- (BOOL)resignFirstResponder
{
    // 修改占位文字颜色
    [self setValue:[UIColor grayColor] forKeyPath:@"_placeholderLabel.textColor"];
    return [super resignFirstResponder];
}

二:可以交换两个方法的实现

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.imageView.image = [UIImage imageNamed:@"333"];
    
}

#import <UIKit/UIKit.h>

@interface UIImage (SWLExtension)

@end

#import "UIImage+SWLExtension.h"
#import <objc/runtime.h>

@implementation UIImage (SWLExtension)

//load:当类加载进内存的时候调用,而且不管有没有子类,都只会调用一次,在main函数之前调用
+(void)load{
    
    Method imageNamedMethod = class_getClassMethod(self, @selector(imageNamed:));
    // 获取xmg_imageNamed
    Method xmg_imageNamedMethod = class_getClassMethod(self, @selector(xmg_imageNamed:));
    
    // 交互方法:runtime
    method_exchangeImplementations(imageNamedMethod, xmg_imageNamedMethod);
}

+ (UIImage *)xmg_imageNamed:(NSString *)name{
    UIImage *image = [UIImage xmg_imageNamed:name];
    if (!image) {
        NSLog(@"失败");
    }else{
        NSLog(@"成功");
    }
    return image;
}

@end

相关文章

网友评论

      本文标题:runtime

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