RunTime動(dòng)態(tài)添加屬性

一. 為什么要?jiǎng)討B(tài)添加屬性?

思考:當(dāng)系統(tǒng)提供的類滿足不了我們要求的時(shí)候, 則需我們手動(dòng)添加屬性,且希望能給系統(tǒng)直接添加屬性;

以NSObject為例 (給NSObject 添加一個(gè)自定義屬性)

  • 想法: 1. 創(chuàng)建一個(gè)子類繼承NSObject, 此時(shí)可以添加屬性;但是并不是直接給系統(tǒng)的類添加;
  • 想法: 2. 給NSObject添加一個(gè)分類, 在分類中我們可以實(shí)現(xiàn)方法, 但是添加屬性, 僅僅只生成方法的聲明;并沒(méi)有方法實(shí)現(xiàn)和生成下劃線成員變量;

二. 此時(shí)考慮使用runtime來(lái)動(dòng)態(tài)實(shí)現(xiàn)給系統(tǒng)的類添加屬性;

tips: 記得區(qū)分屬性與成員變量

{
    NSString *_name; // 成員變量
}

@property (nonatomic, strong)NSString *name; // 成員屬性

三. 實(shí)現(xiàn)步驟:

1.0 給NSObject 添加一個(gè)分類(Property),在里面添加一個(gè)自定義屬性;

    #import <Foundation/Foundation.h>
    #import <Foundation/Foundation.h>

    @interface NSObject (Property)

    @property NSString *name; // 既然沒(méi)有生成成員變量,那么無(wú)需策略進(jìn)行修飾 

    @end

2.0 導(dǎo)入runtime的頭文件,
3.0 在.h文件中實(shí)現(xiàn)name方法的getter 和setter方法

    #import "NSObject+Property.h"
    #import <objc/message.h>

    @implementation NSObject (Property)

    - (void)setName:(NSString *)name
    {

         // 保存name
        // 動(dòng)態(tài)添加屬性的本質(zhì)是:讓對(duì)象的某個(gè)屬性與值產(chǎn)生關(guān)聯(lián)
        objc_setAssociatedObject(self, "name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
   }

   - (NSString *)name
    {
          // 獲取對(duì)應(yīng)屬性的值
         return objc_getAssociatedObject(self, "name");
    
    }
     @end
    解析:
       // 關(guān)聯(lián)值的方法
       objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
    
        object:保存到哪個(gè)對(duì)象中 
        key:用什么屬性保存?zhèn)魅氲闹?        value:需保存值
        policy:策略,strong,weak等
    
        // 獲取值的方法:
        objc_getAssociatedObject(id object, const void *key);
    
         object:從哪個(gè)對(duì)象中獲取值
         key: 用什么屬性獲取值

四.驗(yàn)證: 在其他文件導(dǎo)入NSObject的分類頭文件,并使用自定義屬性;

    NSObject *objc = [[NSObject alloc] init];
    objc.name = @"abel";
    
    NSLog(@"%@",objc.name);  // 可打印出: abel

題外話:

對(duì)于如何記住runtime的方法, 只有一個(gè)原則:誰(shuí)的事情誰(shuí)處理;故我們可判斷runtime方法的前綴是什么.

以本文方法為例, 我們需要給系統(tǒng)添加一個(gè)自定義屬性;
動(dòng)態(tài)添屬性的本質(zhì)是:讓對(duì)象的某個(gè)屬性與值(其他對(duì)象)產(chǎn)生關(guān)聯(lián);

則runtime方法前綴應(yīng)該是objc(對(duì)象) ,_setAssociatedObject(關(guān)聯(lián)另一個(gè)對(duì)象)
objc_getAssociatedObject(id object, const void *key)方法亦是如此;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容