ios 中的关联对象
2019獨角獸企業(yè)重金招聘Python工程師標準>>>
?? 關(guān)聯(lián)對象的簡單使用:
#import "wangmumu.h" @interface wangmumu () { } @end static char staticString; @implementation SHVCarsViewController - ( void )viewDidLoad { ???? [ super viewDidLoad]; ???? // Do any additional setup after loading the view. ????? ???? self .edgesForExtendedLayout= UIRectEdgeNone ; ???? self .tableView.hidden = YES ; ???? UIButton *btn = [[ UIButton alloc]initWithFrame:CGRectMake(100, 100, 100, 100)]; ???? btn.backgroundColor = [ UIColor grayColor]; ???? [btn addTarget: self action: @selector (btnn:) forControlEvents: UIControlEventTouchUpInside ]; ???? objc_setAssociatedObject(btn, &staticString, @ "aaaa" , OBJC_ASSOCIATION_RETAIN_NONATOMIC); ???? [ self .view addSubview:btn]; ????? ????? } - ( void )btnn:( UIButton *)btn{ ???? NSString *str = objc_getAssociatedObject(btn, &staticString); ???? NSLog (@ "%@" ,str); } /* objc_setAssociatedObject(btn, &staticString, @"aaaa", OBJC_ASSOCIATION_RETAIN_NONATOMIC); 有四個參數(shù) 1.被關(guān)聯(lián)的對象 2.要關(guān)聯(lián)的對象的鍵值,一般設置成靜態(tài)的,用于獲取關(guān)聯(lián)對象的值 3.要傳得值 一般是靜態(tài)變量 4.關(guān)聯(lián)時采用的協(xié)議,有assign,retain,copy等協(xié)議 點擊進去選取枚舉 */ ? ? ? ? ? ?關(guān)聯(lián)對象(Associated Object)
關(guān)聯(lián)對象是Runtime中一個非常實用的特性,不過可能很容易被忽視。
關(guān)聯(lián)對象類似于成員變量,不過是在運行時添加的。我們通常會把成員變量(Ivar)放在類聲明的頭文件中,或者放在類實現(xiàn)的@implementation后面。但這有一個缺點,我們不能在分類中添加成員變量。如果我們嘗試在分類中添加新的成員變量,編譯器會報錯。
我們可能希望通過使用(甚至是濫用)全局變量來解決這個問題。但這些都不是Ivar,因為他們不會連接到一個單獨的實例。因此,這種方法很少使用。
Objective-C針對這一問題,提供了一個解決方案:即關(guān)聯(lián)對象(Associated Object)。
我們可以把關(guān)聯(lián)對象想象成一個Objective-C對象(如字典),這個對象通過給定的key連接到類的一個實例上。不過由于使用的是C接口,所以key是一個void指針(const void *)。我們還需要指定一個內(nèi)存管理策略,以告訴Runtime如何管理這個對象的內(nèi)存。這個內(nèi)存管理的策略可以由以下值指定:
1 2 3 4 5 OBJC_ASSOCIATION_ASSIGN OBJC_ASSOCIATION_RETAIN_NONATOMIC OBJC_ASSOCIATION_COPY_NONATOMIC OBJC_ASSOCIATION_RETAIN OBJC_ASSOCIATION_COPY當宿主對象被釋放時,會根據(jù)指定的內(nèi)存管理策略來處理關(guān)聯(lián)對象。如果指定的策略是assign,則宿主釋放時,關(guān)聯(lián)對象不會被釋放;而如果指定的是retain或者是copy,則宿主釋放時,關(guān)聯(lián)對象會被釋放。我們甚至可以選擇是否是自動retain/copy。當我們需要在多個線程中處理訪問關(guān)聯(lián)對象的多線程代碼時,這就非常有用了。
我們將一個對象連接到其它對象所需要做的就是下面兩行代碼:
1 2 3 static char myKey; ? objc_setAssociatedObject(self, &myKey, anObject, OBJC_ASSOCIATION_RETAIN);在這種情況下,self對象將獲取一個新的關(guān)聯(lián)的對象anObject,且內(nèi)存管理策略是自動retain關(guān)聯(lián)對象,當self對象釋放時,會自動release關(guān)聯(lián)對象。另外,如果我們使用同一個key來關(guān)聯(lián)另外一個對象時,也會自動釋放之前關(guān)聯(lián)的對象,這種情況下,先前的關(guān)聯(lián)對象會被妥善地處理掉,并且新的對象會使用它的內(nèi)存。
1 id anObject = objc_getAssociatedObject(self, &myKey);我們可以使用objc_removeAssociatedObjects函數(shù)來移除一個關(guān)聯(lián)對象,或者使用objc_setAssociatedObject函數(shù)將key指定的關(guān)聯(lián)對象設置為nil。
我們下面來用實例演示一下關(guān)聯(lián)對象的使用方法。
假定我們想要動態(tài)地將一個Tap手勢操作連接到任何UIView中,并且根據(jù)需要指定點擊后的實際操作。這時候我們就可以將一個手勢對象及操作的block對象關(guān)聯(lián)到我們的UIView對象中。這項任務分兩部分。首先,如果需要,我們要創(chuàng)建一個手勢識別對象并將它及block做為關(guān)聯(lián)對象。如下代碼所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 - (void)setTapActionWithBlock:(void (^)(void))block { ???? UITapGestureRecognizer *gesture = objc_getAssociatedObject(self, &kDTActionHandlerTapGestureKey); ? ???? if (!gesture) ???? { ???????? gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(__handleActionForTapGesture:)]; ???????? [self addGestureRecognizer:gesture]; ???????? objc_setAssociatedObject(self, &kDTActionHandlerTapGestureKey, gesture, OBJC_ASSOCIATION_RETAIN); ???? } ? ???? objc_setAssociatedObject(self, &kDTActionHandlerTapBlockKey, block, OBJC_ASSOCIATION_COPY); }這段代碼檢測了手勢識別的關(guān)聯(lián)對象。如果沒有,則創(chuàng)建并建立關(guān)聯(lián)關(guān)系。同時,將傳入的塊對象連接到指定的key上。注意block對象的關(guān)聯(lián)內(nèi)存管理策略。
手勢識別對象需要一個target和action,所以接下來我們定義處理方法:
1 2 3 4 5 6 7 8 9 10 11 12 - ( void )__handleActionForTapGesture:(UITapGestureRecognizer *)gesture { ???? if (gesture.state == UIGestureRecognizerStateRecognized) ???? { ???????? void (^action)( void ) = objc_getAssociatedObject(self, &kDTActionHandlerTapBlockKey); ? ???????? if (action) ???????? { ???????????? action(); ???????? } ???? } }我們需要檢測手勢識別對象的狀態(tài),因為我們只需要在點擊手勢被識別出來時才執(zhí)行操作。
從上面的例子我們可以看到,關(guān)聯(lián)對象使用起來并不復雜。它讓我們可以動態(tài)地增強類現(xiàn)有的功能。我們可以在實際編碼中靈活地運用這一特性。
轉(zhuǎn)載于:https://my.oschina.net/u/2329800/blog/652049
總結(jié)
以上是生活随笔為你收集整理的ios 中的关联对象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: Javascript中var that=
 - 下一篇: iOS开发之裁剪圆形头像