objective-c 中的关联介绍
2015-06-12 15:15
423 查看
objective-c 中的关联介绍
转载请注明CSDN博客上的出处:http://blog.csdn.net/daiyibo123/article/details/46471993
如何设置关联
我们可以使用下面的方法来关联属性:objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
被关联的对象,下面举的例子中关联到了UIAlertView
要关联的对象的键值,一般设置成静态的,用于获取关联对象的值
要关联的对象的值,从接口中可以看到接收的id类型,所以能关联任何对象
关联时采用的协议,有assign,retain,copy等协议,具体可以参考官方文档
可以通过下面的方法来获取我们刚刚关联的object:
objc_getAssociatedObject(id object, const void *key);
被关联的对象
要关联的对象的键值,一般设置成静态的,用于获取关联对象的值
简单运用
下面是简单地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的动态特性
- OC中全局NSMutableArray对象不能addObject局部对象
- NGUI 滑动页(UIToggle和UIToggledObjects)
- objective-c基础语法之字典NSDIctionary、NSMutableDictionary
- Object Clustering - POJ 3241 曼哈顿最小生成树
- NGUI Table页(UIToggle和UIToggledObjects)
- objective-c基础语法之数组NSArray、NSMutableArray
- Objective-C马路成魔【14-关键C语言功能】
- ECMAScript6新增值比较函数Object.is
- 轻松学习之 Objective-C消息转发
- 在主线程中慎用WaitForSingleObject (WaitForMultipleObjects)
- ECMAScript6新增值比较函数Object.is
- Qt Object模型及其线程和事件处理
- Objective-C 类的继承、方法的重写和重载
- 【Effective Objective-C 2.0读书笔记】第五章:内存管理
- 浅析C# 中object sender与EventArgs e (转)
- Objective-C开发编码规范
- Objective-C开发编码规范
- Swift与Objective-C:重新认识苹果的编程语言(1)
- PHP、JAVA、C#、Object-C 通用的DES加密