亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

OC runtime學習筆記之關聯對象

2019-10-21 18:39:42
字體:
來源:轉載
供稿:網友

前言

Objective-C 不能動態的添加一些屬性到對象上,和其他的一些原生支持這點的語言不一樣。所以之前你都不得不努力為未來要增加的變量預留好空間。在 Mac OS X 10.6 中,Objective-C 的 Runtime 已經原生的支持這個功能了。

OC runtime 中關聯對象的方法相信大家都使用過,但是其原理和內部實現就很多人不知道。這篇文章就來講解一下 OC runtime 之關聯對象,下面直接步入正題。

runtime 關聯對象原理

runtime 中提供的 API 如下:

/// 對象關聯策略typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) { OBJC_ASSOCIATION_ASSIGN = 0,  /**< 關聯一個弱引用 */ OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< 指定關聯一個強引用. 非原子性. */ OBJC_ASSOCIATION_COPY_NONATOMIC = 3, /**< 指定關聯一個拷貝引用. 非原子性. */ OBJC_ASSOCIATION_RETAIN = 01401, /**< 指定關聯一個強引用.原子性. */ OBJC_ASSOCIATION_COPY = 01403  /**< 指定關聯一個拷貝引用.原子性. */};/**  * 用給定的 key 和關聯策略 policy 為指定的 object 設置關聯關系 */void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy);/**  * 通過給定的 object 和 key 拿到關聯的對象 */id objc_getAssociatedObject(id object, const void * key);/**  * 移除給定 object 所有關聯的關系 */void objc_removeAssociatedObjects(id object);

runtime 的 API 很簡單,實際上工作中使用 runtime 的關聯對象也很方便,如下:

static const void * _Nonnull titleKey = @"titleKey";- (void)setTitle:(NSString *)title{ objc_setAssociatedObject(self, titleKey, key, OBJC_ASSOCIATION_RETAIN);}- (NSString *)title{ return objc_getAssociatedObject(self, titleKey);}

如此簡單強大的功能,如果想要觀察系統的實現,可以找關聯對象的源碼,我們可以從objc 源碼中拿到,

從源碼中,可以找到以上三個 API 的實現如下:

OC,runtime

以 objc_setAssociatedObject 方法為例,方法內部調用的一個內部方法,參數同上,進入內部方法

/// 方法為我加過注釋的代碼。void _object_set_associative_reference(id object, void *key, id value, uintptr_t policy) {  // 取原來的綁定關系,新綁定關系原來關系為空 ObjcAssociation old_association(0, nil); // 驗證參數 id new_value = value ? acquireValue(value, policy) : nil; { // 內部綁定關系管理器.內部管理一個全局 AssociationsHashMap AssociationsManager manager; // 管理器中的綁定關系Map AssociationsHashMap &associations(manager.associations()); // 生成偽裝地址。處理參數 object 地址 disguised_ptr_t disguised_object = DISGUISE(object); if (new_value) {  // 打破原來存在的綁定關系  AssociationsHashMap::iterator i = associations.find(disguised_object); // 以偽裝地址為key 在AssociationsHashMap找objc 對應的二級 Map  if (i != associations.end()) {  // 二級Map存在。并取二級map: ObjectAssociationMap  ObjectAssociationMap *refs = i->second;  // 同樣的方法找到 ObjectAssociationMap 中綁定關系  ObjectAssociationMap::iterator j = refs->find(key); // 通過key 在ObjectAssociationMap 中找ObjcAssociation  if (j != refs->end()) {   // 找到原來 ObjcAssociation 關系,直接賦值old_association   old_association = j->second;   j->second = ObjcAssociation(policy, new_value);  } else {   // 不存在 -> 重新創建一次   (*refs)[key] = ObjcAssociation(policy, new_value);  }  } else {  // 不存在二級Map 就直接從新創建  ObjectAssociationMap *refs = new ObjectAssociationMap;  associations[disguised_object] = refs;  (*refs)[key] = ObjcAssociation(policy, new_value);  object->setHasAssociatedObjects();  } } else {  // 未傳 value ,直接設置關聯關系為nil。移除原來的綁定關系  AssociationsHashMap::iterator i = associations.find(disguised_object);  if (i != associations.end()) {  ObjectAssociationMap *refs = i->second;  ObjectAssociationMap::iterator j = refs->find(key);  if (j != refs->end()) {   old_association = j->second;   refs->erase(j);  }  } } } // 釋放 old value. if (old_association.hasValue()) ReleaseValue()(old_association);}

從源碼中可以看到維護對象關聯的對象主要有四個

AssociationsManager  // 維護關聯關系的全局管理者 ---> 保存AssociationsHashMap
AssociationsHashMap  // 保存關聯關系的HashMap ---> 保存對象對應的關聯關系的Map
ObjectAssociationMap // 對象關聯關系的Map,二級Map
ObjcAssociation      // 關聯關系

它們的關系用圖像表示如下:

OC,runtimeruntime

相當于從我們的對象外部重新創建并管理了一套對象關聯機制,通過雙層 hashMap 來維護對象之間的關聯關系。其中 AssociationsHashMap(外層Map)是存放在 AssociationsManager 中的全局靜態 map。通過要關聯對象的內存地址處理得到和對象唯一綁定的 key 在 map 中保存和對象相關的ObjectAssociationMap,此 map 又維護一個一個的 ObjcAssociation (關聯策略和值)。

以上以 objc_setAssociatedObject 為例講解了關聯對象的原理,objc_getAssociatedObject和objc_removeAssociatedObjects 原理也是一樣。

思維拓展

runtime 中對象關聯的原理如上,學習了蘋果源碼中的思想。可以發現工作中很多類似的數據存儲恰好能借鑒一下。

恰好下午研究 runtime 對象關聯原理的時候,朋友問我一個多用戶系統的實現邏輯。

大意是:

  • 用戶通過手機號登錄后會在內存中生成用戶信息表,表中可以保存用戶的諸如:個人基本信息、聯系人信息、錢包信息……
  • 用戶退出登錄后,信息不會丟失。
  • 其他用戶登錄后,會同樣創建對應的用戶信息表,并保存
  • 之前用戶登錄后,依然能查看之前自己的用戶信息

看到這個問題,我直接感覺 runtime 中對象關聯的實現恰好就是這個問題的極好實現。

通過用戶登錄id為 key 創建用戶信息Map。確定每個用戶id對應唯一一個用戶信息表,用戶信息表中想保存什么信息就自定義啦。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到IOS開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久久久成人| 91亚洲va在线va天堂va国| 久久久久北条麻妃免费看| 亚洲欧洲国产一区| 日韩欧美在线国产| 国产精品久久久久久久久粉嫩av| 久久综合国产精品台湾中文娱乐网| 91久久精品国产| 激情成人在线视频| 国产成人精品视频在线观看| 国产午夜精品视频免费不卡69堂| 国产精品黄视频| 日韩第一页在线| 久久亚洲一区二区三区四区五区高| 国产亚洲精品日韩| 欧美国产日韩精品| 欧美有码在线观看视频| 久久香蕉频线观| 欧美日韩在线视频首页| 色婷婷**av毛片一区| 中文字幕亚洲国产| 亚洲精品黄网在线观看| 国产一区二区成人| 国产一级揄自揄精品视频| 久操成人在线视频| 亚洲娇小xxxx欧美娇小| 国产视频久久久久| 91久久精品日日躁夜夜躁国产| 日韩视频一区在线| 国产自产女人91一区在线观看| 亚洲欧美国产精品va在线观看| 久久久噜久噜久久综合| 欧美一级电影免费在线观看| 亚洲国产高清福利视频| 欧美精品日韩www.p站| 精品久久久久久久久久ntr影视| 欧美激情一二区| 91精品久久久久久久久不口人| 亚洲japanese制服美女| 精品久久久免费| 亚洲sss综合天堂久久| 欧美日韩一区免费| 81精品国产乱码久久久久久| 92福利视频午夜1000合集在线观看| 黄色一区二区三区| 日韩成人性视频| 久久久久这里只有精品| 搡老女人一区二区三区视频tv| 久久综合伊人77777| 色综合五月天导航| 4388成人网| 亚洲综合成人婷婷小说| 日韩三级影视基地| 欧美精品激情在线| 亚洲伊人第一页| 色悠久久久久综合先锋影音下载| 精品久久久久久中文字幕| 国内精品视频久久| 97精品国产97久久久久久| 国产成人在线精品| 欧美一区视频在线| 亚洲国产成人久久综合| 黑人巨大精品欧美一区二区一视频| 国产不卡视频在线| 久久夜精品va视频免费观看| 亚洲免费av网址| 久久久久久亚洲精品中文字幕| 国产在线999| 色樱桃影院亚洲精品影院| 国产不卡一区二区在线播放| 夜夜躁日日躁狠狠久久88av| 久久视频在线直播| 精品久久久久久亚洲国产300| 日本成人黄色片| 欧美性猛交xxxx乱大交3| 色777狠狠综合秋免鲁丝| 午夜精品久久久久久99热软件| 国产精品99久久久久久久久| 亚洲自拍av在线| 日韩精品在线免费观看视频| 韩国福利视频一区| 国产欧美一区二区三区久久人妖| 亚洲一区二区在线播放| 亚洲成人网在线观看| 欧美成人黑人xx视频免费观看| 欧美日韩成人黄色| 正在播放欧美一区| 裸体女人亚洲精品一区| 国产精品电影网| 78色国产精品| 欧美激情亚洲一区| 91夜夜揉人人捏人人添红杏| 欧美激情精品久久久久久久变态| 亚洲精品456在线播放狼人| 亚洲视频在线观看网站| 国产精品自拍偷拍视频| 欧美一级淫片aaaaaaa视频| 国产成人一区三区| 精品久久久久久久久久久久| 亚洲国产美女精品久久久久∴| 国产精品99免视看9| 亚洲国产成人91精品| 精品久久香蕉国产线看观看亚洲| 欧美男插女视频| 国产精品爱啪在线线免费观看| 91在线网站视频| 欧美视频一区二区三区…| 日韩一中文字幕| 欧美一区二三区| 国产欧美日韩专区发布| 亚洲第一福利网| 欧美成人免费全部观看天天性色| 亚洲精品欧美一区二区三区| 国产一区二区三区在线观看视频| 国产脚交av在线一区二区| 国产成人精品综合| 伦伦影院午夜日韩欧美限制| 亚洲中国色老太| 日本伊人精品一区二区三区介绍| 亚洲a在线观看| www.美女亚洲精品| 国产在线观看精品| 91精品中文在线| 国产精品中文字幕在线观看| 国产人妖伪娘一区91| 成人福利免费观看| 国产精品视频区| 中文字幕精品一区二区精品| 色综合久久中文字幕综合网小说| 日韩成人在线视频| 国产午夜精品全部视频播放| 国产精品va在线| 91黄色8090| 在线观看欧美日韩国产| 成人激情黄色网| 91av免费观看91av精品在线| 亲爱的老师9免费观看全集电视剧| 国产一区二区日韩| 成人深夜直播免费观看| 亚洲欧美另类人妖| 日韩欧美在线第一页| 欧美日韩免费一区| 欧美丰满片xxx777| 国产精品久久久久久久久久久久久| 亚洲美女在线看| 97免费中文视频在线观看| 97色在线观看| 91久久精品久久国产性色也91| 欧美有码在线视频| 在线观看日韩www视频免费| 丝袜美腿精品国产二区| 久久亚洲国产精品成人av秋霞| 欧美极品xxxx| 亚洲网站在线观看| 欧美成人免费全部观看天天性色| 成人av电影天堂| 亚洲区在线播放| 国产精品免费电影| 中文综合在线观看| 日韩免费在线观看视频| 精品高清一区二区三区| 欧美日韩裸体免费视频| 精品久久久久久中文字幕| 久久婷婷国产麻豆91天堂|