runtime關聯屬性

關聯API介紹


咱們先看看關聯API,只有這三個API,使用也是很是簡單的: 安全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 
/**
* Sets an associated value for a given object using a given key and association policy.
*
* @param object The source object for the association.
* @param key The key for the association.
* @param value The value to associate with the key key for object. Pass nil to clear an existing association.
* @param policy The policy for the association. For possible values, see 「Associative Object Behaviors.」
*
* @see objc_setAssociatedObject
* @see objc_removeAssociatedObjects
*/
void objc_setAssociatedObject ( id object , const void *key , id value , objc_AssociationPolicy policy )
 
/**
* Returns the value associated with a given object for a given key.
*
* @param object The source object for the association.
* @param key The key for the association.
*
* @return The value associated with the key \e key for \e object.
*
* @see objc_setAssociatedObject
*/
id objc_getAssociatedObject ( id object , const void *key )
 
/**
* Removes all associations for a given object.
*
* @param object An object that maintains associated objects.
*
* @note The main purpose of this function is to make it easy to return an object
*  to a "pristine state」. You should not use this function for general removal of
*  associations from objects, since it also removes associations that other clients
*  may have added to the object. Typically you should use \c objc_setAssociatedObject
*  with a nil value to clear an association.
*
* @see objc_setAssociatedObject
* @see objc_getAssociatedObject
*/
void objc_removeAssociatedObjects ( id object )
 

實際上,咱們幾乎不會使用到objc_removeAssociatedObjects函數,這個函數的功能是移除指定的對象上全部的關聯。 ide

設置關聯值

對於設置關聯,咱們須要使用下面的API關聯起來: 函數

1
2
3
 
void objc_setAssociatedObject ( id object , const void *key , id value , objc_AssociationPolicy policy )
 

參數說明: ui

  • object:與誰關聯,一般是傳self
  • key:惟一鍵,在獲取值時經過該鍵獲取,一般是使用static const void *來聲明
  • value:關聯所設置的值
  • policy:內存管理策略,好比使用copy

獲取關聯值

若是咱們要獲取所關聯的值,須要經過key來獲取,調用以下函數: this

1
2
3
 
id objc_getAssociatedObject ( id object , const void *key )
 

參數說明: atom

  • object:與誰關聯,一般是傳self,在設置關聯時所指定的與哪一個對象關聯的那個對象
  • key:惟一鍵,在設置關聯時所指定的鍵

關聯策略

咱們先看看設置關聯時所指定的policy,它是一個枚舉類型,看官方說明: spa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
/**
* Policies related to associative references.
* These are options to objc_setAssociatedObject()
*/
typedef OBJC_ENUM ( uintptr_t , objc_AssociationPolicy ) {
     OBJC_ASSOCIATION_ASSIGN = 0 ,            /**< Specifies a weak reference to the associated object. */
     OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1 , /**< Specifies a strong reference to the associated object.
                                            *   The association is not made atomically. */
     OBJC_ASSOCIATION_COPY_NONATOMIC = 3 ,    /**< Specifies that the associated object is copied.
                                            *   The association is not made atomically. */
     OBJC_ASSOCIATION_RETAIN = 01401 ,        /**< Specifies a strong reference to the associated object.
                                            *   The association is made atomically. */
     OBJC_ASSOCIATION_COPY = 01403            /**< Specifies that the associated object is copied.
                                            *   The association is made atomically. */
} ;
 

咱們說明一下各個值的做用: .net

  • OBJCASSOCIATIONASSIGN:表示弱引用關聯,一般是基本數據類型,如int、float
  • OBJCASSOCIATIONRETAIN_NONATOMIC:表示強(strong)引用關聯對象
  • OBJCASSOCIATIONCOPY_NONATOMIC:表示關聯對象copy
  • OBJCASSOCIATIONRETAIN:表示強(strong)引用關聯對象,但不是線程安全的
  • OBJCASSOCIATIONCOPY:表示關聯對象copy,但不是線程安全的

擴展屬性


咱們來寫一個例子,擴展UIControl添加Block版本的TouchUpInside事件。 線程

擴展頭文件聲明: code

1
2
3
4
5
6
7
8
9
10
11
 
#import <UIKit/UIKit.h>
 
typedef void ( ^ HYBTouchUpBlock ) ( id sender ) ;
 
@interface UIControl ( HYBBlock )
 
@property ( nonatomic , copy ) HYBTouchUpBlock hyb_touchUpBlock ;
 
@end
 

擴展實現文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 
#import "UIControl+HYBBlock.h"
#import <objc/runtime.h>
 
static const void *sHYBUIControlTouchUpEventBlockKey = "sHYBUIControlTouchUpEventBlockKey" ;
 
@implementation UIControl ( HYBBlock )
 
- ( void ) setHyb_touchUpBlock : ( HYBTouchUpBlock ) hyb _ touchUpBlock {
   objc_setAssociatedObject ( self ,
                           sHYBUIControlTouchUpEventBlockKey ,
                           hyb_touchUpBlock ,
                           OBJC_ASSOCIATION_COPY ) ;
  
   [ self removeTarget :self
              action : @selector ( hybOnTouchUp : )
    forControlEvents :UIControlEventTouchUpInside ] ;
  
   if ( hyb_touchUpBlock ) {
     [ self addTarget :self
             action : @selector ( hybOnTouchUp : )
   forControlEvents :UIControlEventTouchUpInside ] ;
   }
}
 
- ( HYBTouchUpBlock ) hyb _ touchUpBlock {
   return objc_getAssociatedObject ( self , sHYBUIControlTouchUpEventBlockKey ) ;
}
 
- ( void ) hybOnTouchUp : ( UIButton * ) sender {
   HYBTouchUpBlock touchUp = self . hyb_touchUpBlock ;
  
   if ( touchUp ) {
     touchUp ( sender ) ;
   }
}
 
@end
 

使用起來很簡單吧!!!


用法,在使用到的類進行 引用category;

   

UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];

    [backBtn setHyb_touchUpBlock:^(id btn){

        NSLog(@"backk");

    }];
就這樣愉快的使用啦
相關文章
相關標籤/搜索