標籤:
關聯引用: 允許開發人員為任何對象附著索引值資料, 很常用的用法是為分類添加屬性.
節目預告
1. 簡單的關聯引用
2. 為UIViewController 添加MBProgressHUD的HUB屬性
3. 為UINavigationBar添加一個view屬性 來完成動態改變UINavigationBar的外觀
官方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 };/**object 來源物件key 關鍵字 唯一靜態變數keyvalue 關聯的對象 value(userAge)關鍵策略 OBJC_ASSOCIATION_COPY*/OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);// 通過 objc_getAssociatedObject擷取關聯對象OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);// 刪除關聯OBJC_EXPORT void objc_removeAssociatedObjects(id object) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);
情景1 :你要用分類為 User添加一個屬性 叫做 userAge, User類在很多地方會用到, 而使用者的年齡不常常被用到, 為了避免不必要的開銷, 分類是個很好的選擇.
首先我建立一個User類
@interface User : NSObject@property (nonatomic, copy) NSString *userName;@end
@implementation User@end
接下來我採用擴充的方式為User添加一個 userAge的屬性.
@interface User (Extensions)@property (nonatomic, copy) NSString *userAge;@end
#import "User+Extensions.h"#import <objc/runtime.h>@implementation User (Extensions)static char userAgeKey;- (NSString *)userAge{ return objc_getAssociatedObject(self, &userAgeKey);}- (void)setUserAge:(NSString *)userAge{ objc_setAssociatedObject(self, &userAgeKey, userAge, OBJC_ASSOCIATION_COPY);}@end
如果單純這樣而使用關聯引用, 我其實覺得很牽強, 表示恨不能理解…
接下來會給出在項目中”很好”的實踐. 囧~.
情景2 : 為UIViewController 擴充一個 HUB屬性, 接下來以 MBProgressHUD為例
#import <UIKit/UIKit.h>@interface UIViewController (HUD)- (void)showHudInView:(UIView *)view hint:(NSString *)hint;@end
#import "UIViewController+HUD.h"#import "MBProgressHUD.h"#import <objc/runtime.h>static const void * httpReqHUDKey = &httpReqHUDKey;@implementation UIViewController (HUD)- (MBProgressHUD *)HUD{ return objc_getAssociatedObject(self, httpReqHUDKey);}- (void)setHUD:(MBProgressHUD *)HUD{ objc_setAssociatedObject(self, httpReqHUDKey, HUD, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}- (void)showHudInView:(UIView *)view hint:(NSString *)hint{ MBProgressHUD *HUD = [[MBProgressHUD alloc] initWithView:view]; HUD.labelText = hint; [view addSubview:HUD]; [HUD show:YES]; [self setHUD:HUD];}@end
可能看到這裡有的同學已經明白了一點點, 說白了, 就是給原有的類擴充一個屬性並且實現我們想要對屬性進行的操作.
情景3 為系統UINavigationBar 擴充一個屬性overlay(UIView) 來實現在很多App中流行的一個互動, 滑動介面的時候導覽列的顯隱功能 — 類似於簡書iOS端App那樣的效果 . 代碼來自一個很有名的三方庫(LTNavigationBar). 反正3000+ 的Star. 沒記錯的話只有幾十行代碼, 想法非常的棒, 用到了關聯屬性, 在GitHub可以找到. 下面的是我寫的一個Demo, 你可以看圖感受一下
如果對於這個Demo比較感興趣 可以下載來看一看 這裡放出地址
https://github.com/summerxx27/MyBlogCode 便於學習與交流.
微博-點我@夏天是個大人了 || QQ群: 498143780
iOS Rumtime 之關聯引用