iOS - runtime

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];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容