objective-c 中的关联介绍
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的主要原理,就是把两个对象相互关联起来,使得其中的一个对象作为另外一个对象的一部分。
参考:
objective-c 中的关联介绍的更多相关文章
- 03_MyBatis基本查询,mapper文件的定义,测试代码的编写,resultMap配置返回值,sql片段配置,select标签标签中的内容介绍,配置使用二级缓存,使用别名的数据类型,条件查询ma
1 PersonTestMapper.xml中的内容如下: <?xmlversion="1.0"encoding="UTF-8"?> < ...
- PHP中遍历关联数组的方法
下面介绍PHP中遍历关联数组的三种方法:foreach <?php $sports = array( 'football' => 'good', 'swimming' => 'ver ...
- SQL Server中约束的介绍
SQL Server中约束的介绍(转载收藏) Posted on 2010-09-03 11:05 grayboy 阅读(8501) 评论(0) 编辑 收藏 作者:GrayBoy 出处:http:// ...
- 转:Http协议中Cookie详细介绍
Http协议中Cookie详细介绍 Cookie总是保存在客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie.内存Cookie由浏览器维护,保存在内存中,浏览器关闭后就消失了, ...
- AutoMapper之ABP项目中的使用介绍
最近在研究ABP项目,昨天写了Castle Windsor常用介绍以及其在ABP项目的应用介绍 欢迎各位拍砖,有关ABP的介绍请看阳光铭睿 博客 AutoMapper只要用来数据转换,在园里已经有很多 ...
- iOS开发UI篇—iPad开发中得modal介绍
iOS开发UI篇—iPad开发中得modal介绍 一.简单介绍 说明1: 在iPhone开发中,Modal是一种常见的切换控制器的方式 默认是从屏幕底部往上弹出,直到完全盖住后面的内容为止 说明2: ...
- 理解Objective C 中id
什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...
- 浅谈Objective—C中的面向对象特性
Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...
- Django model中 双向关联问题,求帮助
Django model中 双向关联问题,求帮助 - 开源中国社区 Django model中 双向关联问题,求帮助
随机推荐
- Find your present (2) (位异或)
Problem Description In the new year party, everybody will get a "special present".Now it's ...
- 自动发布工具版本从python2升级成python3后遇到的种种问题(涉及paramiko,Crypto,zipfile等等)
从在公司实习到正式入职,一直还在被同事使用的是我写的一个自动发布工具.该工具的主要功能是:开发人员给出需要更新的代码包(zip格式),测试人员将该代码包部署到测服,这些代码包和JIRA数据库里的项目信 ...
- Umbraco TextBoxFor 如何加样式和属性
前些天一直在找免费的CMS开源代码,搜索了很多,大都是介绍CMS开源系统的的文章或者是安装的主要流程.再深的也有但是都是很多年前的文章.我一个英语半吊子加MVC零基础只能像缓慢爬行的蜗牛一步步走了.为 ...
- GHOST备份
整理日: 2015年2月16日 GHOST Disk2GHO STEP01 STEP02 STEP03 STEP04 STEP05 STEP06 STEP07 STEP08 STEP09 STEP10
- nutch 1.7 修改代码后如何编译发布,并集群采集攻略
nutch 1.3之后,分布式的可执行文件与单机可执行文件进行了分离 接上篇,nutch 1.7 导入 eclipse 本篇所要解决的问题:nutch下载下来经过简单的配置即可进行采集,但有时候我们需 ...
- Contest 20140923 登月计划 BabyStepGaintStep
登月计划 查看 提交 统计 提问 总时间限制: 40000ms 内存限制: 256000kB 描述 HJA在和学弟学数学,于是便有了一道非常简单的数学题:求满足 的最小自然数x. 输入 输入数据一 ...
- app内购提示,您已购买此商品,但未下载
出现这样的问题,是支付没有finish造成的,一般在支付过程中断网了,下次再购买同一商品的时候就会出现这样的问题, 解决办法,在点击购买的时候判断支付队列中是否有为finish的商品,若有,则进行处理 ...
- Hibernate 缓存 关于注解方式
要引入 import org.hibernate.annotations.Cache; 在类前面添加: @Cache(usage= CacheConcurrencyStrategy.NONSTRICT ...
- 【HDOJ】1823 Luck and Love
二维线段树.wa了几次,不存在输出-1,而不再是一位小数. #include <cstdio> #include <cstring> #define MAXN 105 #def ...
- bzoj3504
这是一道最大流的题目首先要引起注意的是,这类多个起点多个终点的问题一定要同时跑,不能分开来跑由于是无向图,也就相当于从起点跑2*n次好,不难想到s向两个起点连边,两终点想t连边,流量为2*an或2*b ...