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];
}
网友评论