objective-c 中的關聯介紹

來源:互聯網
上載者:User

標籤:objective   關聯   

objective-c 中的關聯介紹

轉載請註明CSDN部落格上的出處:
http://blog.csdn.net/daiyibo123/article/details/46471993

如何設定關聯

我們可以使用下面的方法來關聯屬性:

objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
  1. 被關聯的對象,下面舉的例子中關聯到了UIAlertView
  2. 要關聯的對象的索引值,一般設定成靜態,用於擷取關聯對象的值
  3. 要關聯的對象的值,從介面中可以看到接收的id類型,所以能關聯任何對象
  4. 關聯時採用的協議,有assign,retain,copy等協議,具體可以參考官方文檔

可以通過下面的方法來擷取我們剛剛關聯的object:

objc_getAssociatedObject(id object, const void *key);
  1. 被關聯的對象
  2. 要關聯的對象的索引值,一般設定成靜態,用於擷取關聯對象的值
簡單運用下面是簡單地viewController類,黏貼直接可以運行:
#import <UIKit/UIKit.h>@interface ViewController : UIViewController@end
#import "ViewController.h"#import <objc/runtime.h>static char kUITableViewIndexKey;@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    UILabel *lable = [[UILabel alloc] initWithFrame:CGRectMake(0, 200, [UIScreen mainScreen].bounds.size.width, 50)];    lable.backgroundColor = [UIColor lightGrayColor];    lable.text = @"關聯屬性";    lable.textColor = [UIColor blackColor];    objc_setAssociatedObject(self, &kUITableViewIndexKey, lable, OBJC_ASSOCIATION_RETAIN_NONATOMIC);//設定一個關聯    [self.view addSubview:objc_getAssociatedObject(self, &kUITableViewIndexKey)];//擷取剛剛關聯的lable}@end

註:在擷取和設定關聯的時候,調用的被關聯對象(代碼中用的是self)和關聯索引值(代碼中用kUITableViewIndexKey)都必須是同一個對象。這樣才可以保證能擷取到關聯對象。

個人理解下面是索引值的較好的運用:

代碼介紹:一個仿系統的TabBarController類(RDVTabBarController,這個是第三方庫,:https://github.com/robbdimitrov/RDVTabBarController)

在建立RDVTabBarController時,建立了兩個UIViewController的擴充,擴充中建立關聯,關聯代碼如下:

@interface UIViewController (RDVTabBarControllerItemInternal)- (void)rdv_setTabBarController:(RDVTabBarController *)tabBarController;@end@interface UIViewController (RDVTabBarControllerItem)@property(nonatomic, readonly) RDVTabBarController *rdv_tabBarController;@end
@implementation UIViewController (RDVTabBarControllerItemInternal)- (void)rdv_setTabBarController:(RDVTabBarController *)tabBarController {    objc_setAssociatedObject(self, @selector(rdv_tabBarController), tabBarController, OBJC_ASSOCIATION_ASSIGN);}@end@implementation UIViewController (RDVTabBarControllerItem)- (RDVTabBarController *)rdv_tabBarController{    RDVTabBarController *tabBarController = objc_getAssociatedObject(self, @selector(rdv_tabBarController));    //這裡使用的遞迴演算法    if (!tabBarController && self.parentViewController) {        tabBarController = [self.parentViewController rdv_tabBarController];    }    return tabBarController;}@end

然後在RDVTabBarController建立中調用ViewController的擴充方法rdv_setTabBarController:(因為RDVTabBarController也是ViewController的子類,所以可以調用)。通過這個方法設定關聯,將TabBarViewController中的childView都和TabBarViewController關聯起來。

下面是RDVTabBarController中調用擴充方法設定關聯的代碼:
(這個簡化了其他與關聯無關的代碼,需要瞭解其他的,自己從github上下載這個第三方庫看源碼。)

- (void)setViewControllers:(NSArray *)viewControllers {        if (viewControllers && [viewControllers isKindOfClass:[NSArray class]]) {       //向TabBarViewController中添加關聯        for (UIViewController *viewController in viewControllers) {            [viewController rdv_setTabBarController:self];        }    } else {        //沒有向TabBarViewController中添加viewController,刪除關聯,刪除TabBarViewCOntroller中的childViewController        for (UIViewController *viewController in _viewControllers) {            [viewController rdv_setTabBarController:nil];        }        _viewControllers = nil;    }}

完成了上面的設定之後,我們就在項目中,直接通過當前啟動並執行viewController來擷取tabBarViewController這個屬性了。

下面是示範代碼:

[self.rdv_tabBarController setTabBarHidden:!_viewController.rdv_tabBarController.tabBarHidden animated:YES];//通過點運算子,調用UIViewController中的擴充方法:`rdv_tabBarController`。然後在`rdv_tabBarController`擴展方法中,遞迴尋找和RDVTabBarViewController關聯的屬性。
運行結果簡介:

簡單運行一個demo,po打出相關RDVTabBarController中相關資訊:

  • 放入TabBarController中的四個NavigationViewController

  • 第一個NavigationViewController,push推入下一個viewController;推入之後,運行上面的“直接通過當前啟動並執行viewController來擷取tabBarViewController”中的代碼:

在這裡遞迴尋找關聯值,第一個ViewController地址為:’0x7f9378e750a0‘沒有進行關聯,找不到。然後跳到父視圖中,地址為:‘0x7f9378d39a70’有相關,找到,不需要在向下尋找。遞迴結束,找到關聯值,返回結果。

小結:

這裡,通過擴充和關聯的結合使用,將RDVTabBarController這個執行個體屬性,和當前的ViewController結合起來。這種思想,在以後自己編寫第三方庫函數的時候,值得借鑒!
總體來說,associative的主要原理,就是把兩個對象相互關聯起來,使得其中的一個對象作為另外一個對象的一部分。

參考:

http://m.blog.csdn.net/blog/csz0102/19555673

objective-c 中的關聯介紹

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.