微點滴:對于OC的runtime運行時的一些理解

runtime 的一些理解, 整理收集了不少網(wǎng)絡的知識, 只是用于自己對runtime的理解,以備以后自己查閱吧
歸納: **
OC是運行時語言,只有在程序運行時,才會去確定對象的類型,并調用類與對象相應的方法。平時編寫的OC代碼, 在程序運行過程中, 其實最終都是轉成了runtime的C語言代碼, runtime算是OC的幕后工作者。利用runtime機制讓我們可以在程序運行時動態(tài)修改類、對象中的所有屬性、方法,就算是私有方法以及私有屬性都是可以動態(tài)修改的。
runtime是屬于OC的底層, 可以進行一些非常底層的操作。在程序運行過程中, 動態(tài)創(chuàng)建一個類, 動態(tài)地為某個類添加屬性\方法, 修改屬性值\方法,遍歷一個類的所有成員變量(屬性)\所有方法等。
相關知識點
Ivar:定義對象的實例變量,包括類型和名字。objc_property_t:定義屬性。這個名字可能是為了防止和Objective-C 1.0中的用戶類型沖突,那時候還沒有屬性。Method:成員方法。這個類型提供了方法的名字(就是
選擇器)、參數(shù)數(shù)量和類型,以及返回值(這些信息合起來稱為方法的簽名),還有一個指向代碼的函數(shù)指針(也就是方法的實現(xiàn)**)。
SEL:定義選擇器。選擇器是方法名的唯一標識符,我理解它就是個字符串。

****運行時應用(一)****——** 攔截系統(tǒng)自帶的方法交換實現(xiàn)**

  1. <objc/runtime.h>
    2.<objc/message.h>

運行時應用(二)—— 使用對象關聯(lián)為分類增加屬性(每個對象的屬性互不干擾)
1、對象的關聯(lián)方法有
將某個值與某個對象關聯(lián)起來,將某個值存儲到某個對象中
利用參數(shù)key將對象中存儲的對應值取出
2、利用分類為每個對象添加屬性(可作為對象的標簽或存儲信息)
運行時應用(三)——實現(xiàn)NSCoding的自動歸檔和自動解檔
當我們需要將一個對象進行歸檔時,都要讓該對象的類遵守NSCoding協(xié)議,再實現(xiàn)歸檔和接檔方法;
但當該類擁有上百個屬性時,那將會花費更多的功夫在重復代碼上,所以使用運行時runtime機制截取類的成員變量,進行賦值
補充: 在設計模式中: 如多態(tài)的一種適配器模式,就是使用的運行時,在程序過程中動態(tài)創(chuàng)建當前需要的類或者控制器, 也就是我們常說的封裝一個基類,后面的都繼承這個類,或者干脆在程序運行過程中動態(tài)創(chuàng)建;

詳解:

Object - C運行時應用(一)—— 攔截系統(tǒng)自帶的方法交換實現(xiàn)

一、什么是運行時
運行時是一套純C語言的API,編譯器最終都會將OC代碼轉化為運行時代碼。
二、運行時常用函數(shù)

1、<objc/runtime.h>
* 獲得某個類的類方法   
   Method class_getClassMethod(Class cls, SEL name)
* 獲得某個對象的對象方法    
  Method class_getInstanceMethod(Class cls, SEL name)
* 交換兩個方法的實現(xiàn)    
  void method_exchangeImplementations(Method m1, Method m2)
* 關聯(lián)對象(將值value與對象object關聯(lián)起來)   
 void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)    
  參數(shù)key:將來可以通過key取出這個存儲的值    
  參數(shù)policy:存儲策略(assign、copy、retain)
* 利用參數(shù)key將對象中存儲的對應值取出   
   id objc_getAssociatedObject(id object, const void *key)
* 獲得某個類的所有成員變量   
   Ivar *class_copyIvarList(Class cls, unsigned int *outCount)(outCount會返回成員變量的總數(shù))
* 獲得成員變量的名字    
  const char *ivar_getName(Ivar v)
* 獲得成員變量的類型    
  const char *ivar_getTypeEncoding(Ivar v)
* 釋放內存    
  void  free(void *) 
(當C語言函數(shù)名中包含了copy、create、retain、new等詞語,那么就需要在最后釋放資源)
2、<objc/message.h>
* 給某個對象發(fā)送某個消息 
  void objc_msgSend(void)

Object - C運行時應用(二)—— 使用對象關聯(lián)為分類增加屬性(每個對象的屬性互不干擾)

一、對象的關聯(lián)方法有

// 將某個值與某個對象關聯(lián)起來,將某個值存儲到某個對象中
1、 void objc_setAssociatedObject(id object, const void *key, id value,objc_AssociationPolicy policy) ,
關聯(lián)對象(將值value與對象object關聯(lián)起來)
參數(shù)key:將來可以通過key取出這個存儲的值
參數(shù)policy:存儲策略(assign、copy、retain)
2、 id objc_getAssociatedObject(id object, const void *key) ,
利用參數(shù)key將對象中存儲的對應值取出

二、利用分類為每個對象添加屬性(可作為對象的標簽或存儲信息)聲明代碼:

@interface NSObject (CX)
/**
 *  為每一個對象添加一個name屬性
 */
@property (nonatomic,copy) NSString *name;
/**
 *  為每個對象添加一個數(shù)組屬性
 */
@property (nonatomic,strong) NSArray *books;
@end

實現(xiàn)代碼:

// 用一個字節(jié)來存儲key值,設置為靜態(tài)私有變量,避免外界修改
static char nameKey;
- (void)setName:(NSString *)name
{
    // 將某個值與某個對象關聯(lián)起來,將某個值存儲到某個對象中
    objc_setAssociatedObject(self, &nameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name
{
    return objc_getAssociatedObject(self, &nameKey);
}

                                                                                                                                     
static char booksKey;
- (void)setBooks:(NSArray *)books
{
    objc_setAssociatedObject(self, &booksKey, books, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
                                                                                                                                     
- (NSArray *)books
{
    return objc_getAssociatedObject(self, &booksKey);
}
                                                                                                         ```                            
測試:

NSString *str = @"xx";
str.name = @"oo";
str.books = @[@"xxoo",@"ooxx"];
NSLog(@"%@,%@",str.name,str.books);

三、對象關聯(lián)的另一種作用:在既有類中使用關聯(lián)對象存放自定義數(shù)據(jù)
      在ios開發(fā)時經常會用到UIAlertView類,該類提供了一種視圖向用戶展示警告信息。該類通過代理協(xié)議來處理用戶的點擊事件,但由于使用了代理就必須把創(chuàng)建警告的視圖和處理按鈕動作的代碼分開;

####**運行時應用(三)——實現(xiàn)NSCoding的自動歸檔和自動解檔**

當我們需要將一個對象進行歸檔時,都要讓該對象的類遵守NSCoding協(xié)議,再實現(xiàn)歸檔和接檔方法。
例如有一個Person類,該類有兩個成員變量

@property (nonatomic,copy) NSString name;
@property (nonatomic,assign) int age;
兩個協(xié)議的實現(xiàn)方法如下
/
*
將對象寫入某個文件時需要調用,在該方法中說明哪些屬性需要存儲
*/

  • (void)encodeWithCoder:(NSCoder )encoder{
    [encoder encodeObject:self.name forKey:@"name"];
    [encoder encodeInt:self.age forKey:@"age"];
    }
    /
    * 從文件中解析對象時會調用,在該方法中解析對象的屬性 */
  • (id)initWithCoder:(NSCoder *)decoder{
    if (self = [super init]) {
    // 解析之后要賦值給屬性
    _name = [decoder decodeObjectForKey:@"name"];
    _age = [decoder decodeIntForKey:@"age"];
    }
    return self;
    }
但當該類擁有上百個屬性時,那將會花費更多的功夫在重復代碼上,所以使用運行時runtime機制截取類的成員變量,進行賦值
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 對于從事 iOS 開發(fā)人員來說,所有的人都會答出【runtime 是運行時】什么情況下用runtime?大部分人能...
    夢夜繁星閱讀 3,812評論 7 64
  • 轉自:http://blog.csdn.net/liangliang103377/article/details/...
    reallychao閱讀 2,542評論 1 20
  • 國家電網(wǎng)公司企業(yè)標準(Q/GDW)- 面向對象的用電信息數(shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 12,412評論 6 13
  • 轉至元數(shù)據(jù)結尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,055評論 0 9
  • 你就是我的小星星,掛在那天上放光明,我已經決定要愛你,就不會輕易放棄。 偶然間看到念蘇閣在征文,心中便按耐不住激動...
    張夢妮閱讀 394評論 0 2

友情鏈接更多精彩內容