引:

非常多人知道能够用Category给已有的类加入一些新方法,可是不同于swift中的extension,Objective-C中的Category(类别)是不支持直接加入属性的。那假设就是须要加入新的属性怎么办呢?有一个办法。使用Runtime中的关联对象技术就能够实现。关于Runtime的说明能够查看这篇博客:传送门:OC中Runtime浅析

Category(类别):

对于不熟悉Category的人,这里也先说明一下Category是什么以及怎么创建Category。

由于一些特殊的须要,我们可能要给现有的类加入一些新的方法。这个需求用继承也能够做到。可是会显得比較重。这时候就能够用Category来达到目的,创建一个已有类的Category,能够给这个类加入你须要的方法,在使用的时候,仅仅须要import你创建的Category,在使用的时候还是使用原来的类。可是你会惊奇的发现他支持你自己在Category中加入的方法。

我们看到的一些名为相似“UINavigationController+Cloudox.h”的文件就是类别了。

那么怎么创建类别呢?

在project中按住command+N来加入新文件,选择Objectiv-C File:

在出来的界面中的File Type选择Category,就是创建类别文件了,File填写我们要加在类别尾巴上的名字,Class选择你要加入类别的已有类。这里我们为UINavigationController加入类别:

类别文件这样就创建成功了。

加入属性

类别能够为已有的类加入方法,可是却不能直接加入属性,由于即使你加入了@property。它既不会生成实例变量,也不会生成setter、getter方法,即使你加入了也无法使用。

所以我们首先须要自己去加入setter、getter方法。这个好办,直接在.m文件中加就能够了,可是要真正加入能够使用的属性,还须要利用Runtime来关联对象,关于关联对象的技术能够看传送门:OC中Runtime浅析,这里仅仅讲怎么用来加入属性,我们在setter方法里关联一个对象。在getter方法里获取相应key关联的对象。就能够啦,代码例如以下,非常easy:

//UINavigationController+Cloudox.h文件
#import <UIKit/UIKit.h> @interface UINavigationController (Cloudox) @property (copy, nonatomic) NSString *cloudox; @end //UINavigationController+Cloudox.m文件
#import "UINavigationController+Cloudox.h"
#import <objc/runtime.h> @implementation UINavigationController (Cloudox) //定义常量 必须是C语言字符串
static char *CloudoxKey = "CloudoxKey"; -(void)setCloudox:(NSString *)cloudox{
/*
objc_AssociationPolicy參数使用的策略:
OBJC_ASSOCIATION_ASSIGN; //assign策略
OBJC_ASSOCIATION_COPY_NONATOMIC; //copy策略
OBJC_ASSOCIATION_RETAIN_NONATOMIC; // retain策略 OBJC_ASSOCIATION_RETAIN;
OBJC_ASSOCIATION_COPY;
*/
/*
关联方法:
objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy); 參数:
* id object 给哪个对象的属性赋值
const void *key 属性相应的key
id value 设置属性值为value
objc_AssociationPolicy policy 使用的策略,是一个枚举值,和copy,retain。assign是一样的,手机开发一般都选择NONATOMIC
*/ objc_setAssociatedObject(self, CloudoxKey, cloudox, OBJC_ASSOCIATION_COPY_NONATOMIC);
} -(NSString *)cloudox{
return objc_getAssociatedObject(self, CloudoxKey);
} @end

注意要使用Runtime须要 import runtime 的框架,如代码所看到的。

如今我们试试效果,我们依照寻常的方式用UINavigationController包装一个控制器作为根视图:

// AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
ViewController *vc = [[ViewController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = nav;
return YES;
}

这个视图控制器中我们须要导入我们的类别文件。然后我们就会发现我们能够通过self.navigationController获取到我们新加入的名为“cloudox”的属性了!我们能够给这个NSString类型的属性赋值,然后获取它进行显示:

#import "UINavigationController+Cloudox.h"

- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Demo";
self.view.backgroundColor = [UIColor lightGrayColor]; // 给UINavigationController新加的属性赋值
self.navigationController.cloudox = @"Hey,this is category's new property!"; UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(([UIScreen mainScreen].bounds.size.width-300)/2, 100, 300, 50)];
label.textColor = [UIColor whiteColor];
label.textAlignment = NSTextAlignmentCenter;
label.text = self.navigationController.cloudox;
[self.view addSubview:label];
}

效果例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ2xvdWRveF8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" title="">

正常获取到而且显示,非常棒。

以上就是给Category加入属性的方法啦。不难,仅仅要了解Runtime中的关联对象技术就能够轻松达到了。


演示样例project:https://github.com/Cloudox/CategoryAddPropertyDemo

版权全部:http://blog.csdn.net/cloudox_

iOS中OC给Category加入属性的更多相关文章

  1. IOS中扩展机制Category和associative

    在ios开发中,有时候会遇到以下的问题,需要在一个类中添加自己的一些属性和方法.一般的做法是重写一个类来继承它,但是有时候就只是需要添加一些简单的属性和方法,那么这样做就显得过于麻烦,其实在IOS中还 ...

  2. iOS中为什么block用copy属性

    1. Block的声明和线程安全Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非ARC ...

  3. iOS开发——高级篇——iOS中为什么block用copy属性

    1. Block的声明和线程安全Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非ARC ...

  4. DFA算法以及ios中OC实现DFA

    DFA不同于苹果手机的idfa DFA全称为:Deterministic Finite Automaton,即确定有穷自动机.其特征为:有一个有限状态集合和一些从一个状态通向另一个状态的边,每条边上标 ...

  5. iOS之Category关联属性

    Objective-C /** 原文件 */ // Person.h #import <Foundation/Foundation.h> @interface Person : NSObj ...

  6. ios中的category与extension

    http://blog.csdn.net/haishu_zheng/article/details/12873151   category和extension用来做类扩展的,可以对现有类扩展功能或者修 ...

  7. ios 中直接修改frame里边某个属性的简便方法

    参考:http://www.cnblogs.com/wengzilin/p/4359865.html 在iOS中view的frame属性使用地太频繁了,尤其是调UI的时候.我们知道,正常情况下我们无法 ...

  8. iOS开发OC基础:Xcode中常见英文总结,OC常见英文错误

    在开发的过程中难免会遇到很多的错误,可是当看到系统给出的英文时,又不知道是什么意思.所以这篇文章总结了Xcode中常见的一些英文单词及词组,可以帮助初学的人快速了解给出的提示.多练习,就肯定能基本掌握 ...

  9. iOS Category 添加属性实现原理 - 关联对象

    iOS Category 添加属性实现原理 - 关联对象 RunTime为Category动态关联对象 使用RunTime给系统的类添加属性,首先需要了解对象与属性的关系.对象一开始初始化的时候其属性 ...

随机推荐

  1. 移动GPU全解读(二)

    [编者按]:本文作者为爱搞机特约作者.技术达人"炮神"@ioncannon. 在上一篇移动GPU解读中,对移动GPU的架构.相关參数进行了介绍,本部分介绍的则是移动GPU的Shad ...

  2. [ReasonML] Named & optional params

    // ::country is named param // ::country=?: which make it optional // because we make ::country=? op ...

  3. checkbox-padding 调整checkbox字体跟图标距离

    有时候我们会遇到需要调整控件中的内容相对于容器的位置.这里有两种情况 1.linearlayout这样的容器中,包含button类的控件,这时候margin可以调节 2.textview中的文字内容 ...

  4. 去掉“此电脑”中的“WPS云文档”图标

    平台:Win10 问题:安装了WPS2019专业版后,此电脑窗口出现了一个WPS云文档图标,无法删除,云文档设置中也无法取消. 解决:打开注册表,定位到HKEY_CURRENT_USER\Softwa ...

  5. BZOJ1195: [HNOI2006]最短母串(Trie图,搜索)

    Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. Input 第一行是一个正整数n(n<=12) ...

  6. vector转数组

    vector转数组 由于vector内部的数据是存放在连续的存储空间,vector转数组事实上只需要获取vector中第一个数据的地址和数据的长度即可.如果仅仅是传参,无需任何操作,直接传地址即可,如 ...

  7. TypeScript深入学习

    基础类型booleannumberstringstring[]//Array<string> 数组类型(ReadonlyArray<string>数组不能修改,也不允许被赋值给 ...

  8. 《从零開始学Swift》学习笔记(Day 59)——代码排版

    原创文章,欢迎转载.转载请注明:关东升的博客 代码排版包括: 空行.空格.断行和缩进等内容.代码排版内容比較多工作量非常多.可是非常重要. 空行 空行将逻辑相关的代码段分隔开.以提高可读性. 下列情况 ...

  9. onWindowFocusChanged-屏幕焦点函数回调情况

    1.这个函数的具体作用不太清楚,但网上有人说是 ,当activity得到或者失去焦点的时候,就会调用这个方法 先看如下代码 @Override public void onWindowFocusCha ...

  10. JVM route

    http://www.linuxidc.com/Linux/2013-06/86446.htm