iOS中OC给Category加入属性
引:
非常多人知道能够用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加入属性的更多相关文章
- IOS中扩展机制Category和associative
在ios开发中,有时候会遇到以下的问题,需要在一个类中添加自己的一些属性和方法.一般的做法是重写一个类来继承它,但是有时候就只是需要添加一些简单的属性和方法,那么这样做就显得过于麻烦,其实在IOS中还 ...
- iOS中为什么block用copy属性
1. Block的声明和线程安全Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非ARC ...
- iOS开发——高级篇——iOS中为什么block用copy属性
1. Block的声明和线程安全Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非ARC ...
- DFA算法以及ios中OC实现DFA
DFA不同于苹果手机的idfa DFA全称为:Deterministic Finite Automaton,即确定有穷自动机.其特征为:有一个有限状态集合和一些从一个状态通向另一个状态的边,每条边上标 ...
- iOS之Category关联属性
Objective-C /** 原文件 */ // Person.h #import <Foundation/Foundation.h> @interface Person : NSObj ...
- ios中的category与extension
http://blog.csdn.net/haishu_zheng/article/details/12873151 category和extension用来做类扩展的,可以对现有类扩展功能或者修 ...
- ios 中直接修改frame里边某个属性的简便方法
参考:http://www.cnblogs.com/wengzilin/p/4359865.html 在iOS中view的frame属性使用地太频繁了,尤其是调UI的时候.我们知道,正常情况下我们无法 ...
- iOS开发OC基础:Xcode中常见英文总结,OC常见英文错误
在开发的过程中难免会遇到很多的错误,可是当看到系统给出的英文时,又不知道是什么意思.所以这篇文章总结了Xcode中常见的一些英文单词及词组,可以帮助初学的人快速了解给出的提示.多练习,就肯定能基本掌握 ...
- iOS Category 添加属性实现原理 - 关联对象
iOS Category 添加属性实现原理 - 关联对象 RunTime为Category动态关联对象 使用RunTime给系统的类添加属性,首先需要了解对象与属性的关系.对象一开始初始化的时候其属性 ...
随机推荐
- UML中的用例图
用例图构成:參与者(actor).用例(use case).子系统(subsystem) 关联(Association) 泛化(Inheritance) 就是通常理解的继承关系,子用例和父用例类似,但 ...
- 《二》Java IO 流的分类介绍
一.根据流向分为输入流和输出流: 注意输入流和输出流是相对于程序而言的. 输出:把程序(内存)中的内容输出到磁盘.光盘等存储设备中 输入:读取外部数据(磁盘.光盘等存储设备的数据)到程序 ...
- 用Navicat连接MySQL数据库出现1251错误:密码方式错误
原因:因为MySQL8.0是最新版密码保存方式,而图形化数据库管理工具还是原先的密码保存方式. 解决方式: 用CMD命令号方式进入MySQL use mysql: ALTER USER 'root'@ ...
- Vue的学习--开始之前的思考
1.前端后端的思考,到底前端做什么工作 有关前端后端工作的区分,曾经有个朋友告诉我:web开发过程,前端负责从将数据从数据接口提取到前端.路由转换.前端交互展示等等所有工作,后端负责处理数据库里面的数 ...
- BZOJ2754: [SCOI2012]喵星球上的点名(AC自动机/后缀自动机)
Description a180285幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成.喵星球上的老师会选择M个串 ...
- http压测工具wrk
安装 wrk支持大多数类UNIX系统,不支持windows.需要操作系统支持LuaJIT和OpenSSL,不过不用担心,大多数类Unix系统都支持.安装wrk非常简单,只要从github上下载wrk源 ...
- vue踩坑记-在项目中安装依赖模块npm install报错
在维护别人的项目的时候,在项目文件夹中安装npm install模块的时候,报错如下: npm ERR! path D:\ShopApp\node_modules\fsevents\node_modu ...
- SpringCloud核心教程 | 第二篇: 使用Intellij中的maven来快速构建Spring Cloud工程
spring cloud简介 spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等.它运行环 ...
- 【Good Bye 2017 B】 New Year and Buggy Bot
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 枚举一下全排列.看看有多少种可以到达终点即可. [代码] #include <bits/stdc++.h> using ...
- 九度OJ—题目1032:ZOJ
题目描写叙述: 读入一个字符串.字符串中包括ZOJ三个字符,个数不一定相等,按ZOJ的顺序输出.当某个字符用完时,剩下的仍然依照ZOJ的顺序输出. 输入: 题目包括多组用例,每组用例占一行,包括ZOJ ...