_cmd以及objc_setAssociatedObject/objc_getAssociatedObject 的使用


一、_cmd

_cmd表示當前方法的selector的一個指針,self表示指向當前對象的一個指針

例如:

比如,我們要打印當前要調用的方法,可以這樣來寫:

- (void)viewDidLoad{

[super viewDidLoad];

NSLog(@"Current method: %@ %@",[self class],NSStringFromSelector(_cmd));}

輸出結果如下:

Project[570:11303] Current method: FirstViewController viewDidLoad

二、objc_setAssociatedObject

來把一個對象與另外一個對象進行關聯。該函數需要四個參數:源對象,關鍵字,關聯的對象和一個關聯策略。

OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)

1.OBJC_EXPORT 打包lib時,用來說明該函數是暴露給外界調用的。

2.id object 表示關聯者,是一個對象,變量名理所當然也是object

3.id value 表示被關聯者,變量名是value,它要關聯到object上的。

4.關鍵字是一個void類型的指針。每一個關聯的關鍵字必須是唯一的。通常都是會采用靜態變量來作為關鍵字。

5.關聯策略表明了相關的對象是通過賦值,保留引用還是復制的方式進行關聯的;還有這種關聯是原子的還是非原子的。這里的關聯策略和聲明屬性時的很類似。這種關聯策略是通過使用預先定義好的常量來表示的。

enum OBJC_ASSOCIATION_ASSIGN = 0,

       OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,

       OBJC_ASSOCIATION_COPY_NONATOMIC = 3,

       OBJC_ASSOCIATION_RETAIN = 01401,

       OBJC_ASSOCIATION_COPY = 01403};

三、於category很像,都擴展了oc對象的屬性,但objc_setAssociatedObject是運行時來擴展屬性,category是編譯時確定了擴展的屬性。

例如:把一個NSString對象關聯到一個NSArray對象上

  1. #import "ViewController.h"
  2. #import <objc/runtime.h>//添加運行時文件
  3. const NSString *associatedKey = @"associate_nsarray_with_nsstring_key";//設置key
  4. @implementation ViewController
  5. - (void)viewDidLoad {
  6. NSArray *array = [NSArray arrayWithObjects:@"111", @"222", @"333", nil];
  7. NSString *string = @"woshishuzi";
  8. // 將string關聯到array上
  9. objc_setAssociatedObject(array, &associatedKey, string, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  10. // 從array中獲取被關聯的對象string
  11. NSString *getAssociatedObject = objc_getAssociatedObject(array, &associatedKey);//string已經變成array的一個屬性了
  12. NSLog(@"%@", getAssociatedObject);}//輸出結果:woshishuzi
  13. @end

四、實現
1.動態向NSObject中添加方法

@interface NSObject (CategoryWithProperty)

@property (nonatomic, strong) NSObject *property;

@end

@implementation NSObject (CategoryWithProperty)

- (NSObject *)property {

return objc_getAssociatedObject(self, @selector(property));

}

- (void)setProperty:(NSObject *)value {

objc_setAssociatedObject(self, @selector(property), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

2.動態擴展屬性

#import "UILabel+Associate.h"

#import <objc/runtime.h>

@implementation UILabel (Associate) static char flashColorKey;

- (void) setFlashColor:(UIColor *) flashColor{

objc_setAssociatedObject(self, &flashColorKey, flashColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

- (UIColor *) getFlashColor{

return objc_getAssociatedObject(self, &flashColorKey);

}

@end

3.斷開關聯

斷開關聯是使用objc_setAssociatedObject函數,傳入nil值即可。

使用函數objc_removeAssociatedObjects可以斷開所有關聯


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM