runtime 在開(kāi)發(fā)過(guò)程中使用的地方還是很多的。比如交換系統(tǒng)方法和自己的方法,達(dá)到實(shí)現(xiàn)自己方法內(nèi)部的一些特殊實(shí)現(xiàn),;比如通過(guò)runtime 動(dòng)態(tài)給分類(lèi)添加屬性;比如獲取當(dāng)前類(lèi)的所有成員變量,屬性和方法。這些都是 runtime 能給我們提供的黑科技。
runtime 從下面幾點(diǎn)開(kāi)始講解:
runtime 獲取類(lèi)的屬性列表
runtime 獲取類(lèi)的成員變量列表
runtime 獲取類(lèi)的方法列表
runtime 交換兩個(gè)方法
runtime 添加屬性
1、runtime 獲取當(dāng)前類(lèi)的屬性列表
unsigned int 類(lèi)似于 NSUInteger 無(wú)符號(hào)整形
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:
得到當(dāng)前類(lèi)的屬性##
RunTimeLearnViewController.m:52
-----getRunTimePropertyList: testArry
現(xiàn)實(shí)證明是正確的,我申明了一個(gè)testArry的數(shù)組,通過(guò) runtime 獲取的當(dāng)前類(lèi)屬性列表就是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)]);
}
得到當(dāng)前類(lèi)的成員變量##
-------getRunTimeIvarList: _testArry
我們都知道,iOS 會(huì)根據(jù)申明的屬性自動(dòng)的生成對(duì)應(yīng)的成員變量。我們申明了一個(gè)testArry數(shù)組屬性,所以也就對(duì)應(yīng)自動(dòng)生成了一個(gè)_testArry成員變量。#
- 3、獲取類(lèi)的方法列表
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)));
}
得到當(dāng)前類(lèi)的方法##
------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 交換兩個(gè)方法
cell的分類(lèi),全局設(shè)置分割線(xiàn)頂頭#
+(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];
}