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 中的关联介绍的更多相关文章

  1. 03_MyBatis基本查询,mapper文件的定义,测试代码的编写,resultMap配置返回值,sql片段配置,select标签标签中的内容介绍,配置使用二级缓存,使用别名的数据类型,条件查询ma

     1 PersonTestMapper.xml中的内容如下: <?xmlversion="1.0"encoding="UTF-8"?> < ...

  2. PHP中遍历关联数组的方法

    下面介绍PHP中遍历关联数组的三种方法:foreach <?php $sports = array( 'football' => 'good', 'swimming' => 'ver ...

  3. SQL Server中约束的介绍

    SQL Server中约束的介绍(转载收藏) Posted on 2010-09-03 11:05 grayboy 阅读(8501) 评论(0) 编辑 收藏 作者:GrayBoy 出处:http:// ...

  4. 转:Http协议中Cookie详细介绍

    Http协议中Cookie详细介绍 Cookie总是保存在客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie.内存Cookie由浏览器维护,保存在内存中,浏览器关闭后就消失了, ...

  5. AutoMapper之ABP项目中的使用介绍

    最近在研究ABP项目,昨天写了Castle Windsor常用介绍以及其在ABP项目的应用介绍 欢迎各位拍砖,有关ABP的介绍请看阳光铭睿 博客 AutoMapper只要用来数据转换,在园里已经有很多 ...

  6. iOS开发UI篇—iPad开发中得modal介绍

    iOS开发UI篇—iPad开发中得modal介绍 一.简单介绍 说明1: 在iPhone开发中,Modal是一种常见的切换控制器的方式 默认是从屏幕底部往上弹出,直到完全盖住后面的内容为止 说明2: ...

  7. 理解Objective C 中id

    什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...

  8. 浅谈Objective—C中的面向对象特性

    Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...

  9. Django model中 双向关联问题,求帮助

    Django model中 双向关联问题,求帮助 - 开源中国社区 Django model中 双向关联问题,求帮助

随机推荐

  1. 使用Windbg来检查内存

    Windbg是一款微软开发的调试windows代码的工具,水很深,不过使用windbg来进行clr的调试则比较简单,windbg使用之前需要进行配置. File->Symbol path-> ...

  2. go bytes缓冲区使用介绍

    缓冲区原理简介: go字节缓冲区底层以字节切片做存储,切片存在长度len与容量cap, 缓冲区写从长度len的位置开始写,当len>cap时,会自动扩容.缓冲区读会从内置标记off位置开始读(o ...

  3. OpenJudge_cdqz 数据结构版块小结

    题目整理 Challenge 0  随机线性存储表-easy Challenge 1  链表数组-easy Challenge 2  可持久化Treap的可持久化运用-hard Challenge 3 ...

  4. [BZOJ 3894] 文理分科 【最小割】

    题目链接:BZOJ - 3894 题目分析 最小割模型,设定一个点与 S 相连表示选文,与 T 相连表示选理. 那么首先要加上所有可能获得的权值,然后减去最小割,即不能获得的权值. 那么对于每个点,从 ...

  5. prototype.js 源码解读(01)

    prototype.js是一个设计的非常优雅且很有实用价值的js基础类库,其源码非常值得研究.研究它的源码不仅能提升个人水平,而且对你打下坚实的js基础也很有帮助.因本人技术水平有限,该解读仅供参考. ...

  6. iOS9 App Thinning(应用瘦身)功能介绍

    iOS9 发布后,产生了一个使 App Thinning 无法正常运行的 bug.在iOS9.0.2 版本中,这个 bug 已经被修复,App Thinning 已经可以正常使用.当你从应用商店(Ap ...

  7. KMP字符串模式匹配详解(转)

    来自CSDN     A_B_C_ABC 网友 KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法.简单匹配算法的时间复杂度为O(m*n);KMP匹配算法.可以证明它的时间复杂度 ...

  8. The Perfect Stall

    poj1274:http://poj.org/problem?id=1274 题意:有n个奶牛和m个谷仓,现在每个奶牛有自己喜欢去的谷仓,并且它们只会去自己喜欢的谷仓吃东西,问最多有多少奶牛能够吃到东 ...

  9. wpf 依赖性属性

    1 依赖性属性的作用 在WPF体系中,只有定义属性为依赖项属性,这个属性才支持样式设置,数据绑定,继承,动画和默认值.也就是 这个属性才能具有WPF中的一些特点. 它支持自动通知UI控件. WPF的属 ...

  10. poj1637

    混合图欧拉回路首先先明确基本概念连通的无向图存在欧拉回路当且仅当不存在奇点连通的有向图当且仅当每个点入度=出度这道题我们显然应该当作连通的有向图来做这个问题的困难之处在于我不知道应该从无向边的什么方向 ...