節目預告
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 關鍵字 唯一靜態變量key value 關聯的對象 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@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@interface UIViewController (HUD) - (void)showHudInView:(UIView *)view hint:(NSString *)hint; @end
#import "UIViewController+HUD.h" #import "MBProgressHUD.h" #importstatic 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, 你可以看圖感受一下
<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPsjnufu21NPa1eK49kRlbW+xyL3PuNDQy8ikIL/J0tTPwtTYwLS/tNK7v7Qg1eLA77fFs/a12Na3PGJyIC8+DQo8YSBocmVmPQ=="https://github.com/summerxx27/MyBlogCode">https://github.com/summerxx27/MyBlogCode 便於學習與交流.