你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS Rumtime 之關聯引用

iOS Rumtime 之關聯引用

編輯:IOS開發綜合
關聯引用: 允許開發者為任何對象附著鍵值數據, 很常用的用法是為分類添加屬性.

節目預告
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"
#import 

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<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPsjnufu21NPa1eK49kRlbW+xyL3PuNDQy8ikIL/J0tTPwtTYwLS/tNK7v7Qg1eLA77fFs/a12Na3PGJyIC8+DQo8YSBocmVmPQ=="https://github.com/summerxx27/MyBlogCode">https://github.com/summerxx27/MyBlogCode 便於學習與交流.

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved