了解OC的都应该知道,在一般情况下,我们是不能向Category中添加属性的,只能添加方法,但有些情况向,我们确实需要向Category中添加属性,而且很多系统的API也有一些在Category添加属性的情况,例如我们属性的UITableView的section和row属性,就是定义在一个名为NSIndexPath的分类里的。 看完后希望对大家有所帮助 如下:
指引如下:
很多人知道可以用Category给已有的类添加一些新方法,但是不同于Swift中的extension,Objective-C中的Category(类别)是不支持直接添加属性的,那如果就是需要添加新的属性怎么办呢?有一个办法,使用Runtime中的关联对象技术就可以实现。关于Runtime的说明可以查看这篇博客:传送门:OC中Runtime浅析
Category(类别):
对于不熟悉Category的人,这里也先说明一下Category是什么以及怎么创建Category。
由于一些特殊的需要,我们可能要给现有的类添加一些新的方法,这个需求用继承也可以做到,但是会显得比较重,这时候就可以用Category来达到目的,创建一个已有类的Category,可以给这个类添加你需要的方法,在使用的时候,只需要import你创建的Category,在使用的时候还是使用原来的类,但是你会惊奇的发现他支持你自己在Category中添加的方法。
我们看到的一些名为类似“UINavigationController+Cloudox.h”的文件就是类别了。
那么怎么创建类别呢?
在工程中按住command+N来添加新文件,选择Objectiv-C File:
在出来的界面中的File Type选择Category,就是创建类别文件了,File填写我们要加在类别尾巴上的名字,Class选择你要添加类别的已有类,这里我们为UINavigationController添加类别:
类别文件这样就创建成功了。
添加属性
类别可以为已有的类添加方法,但是却不能直接添加属性,因为即使你添加了@property,它既不会生成实例变量,也不会生成setter、getter方法,即使你添加了也无法使用。
所以我们首先需要自己去添加setter、getter方法,这个好办,直接在.m文件里加就可以了,但是要真正添加可以使用的属性,还需要利用Runtime来关联对象,关于关联对象的技术可以看传送门:OC中Runtime浅析,这里只讲怎么用来添加属性,我们在setter方法里关联一个对象,在getter方法里获取对应key关联的对象,就可以啦,代码如下,很简单:
//UINavigationController+Cloudox.h文件
#import
@interface UINavigationController (Cloudox)
@property (copy, nonatomic) NSString *cloudox;
@end
//UINavigationController+Cloudox.m文件
#import "UINavigationController+Cloudox.h"
#import
@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);
}
@end123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
注意要使用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;
}1234567
这个视图控制器中我们需要导入我们的类别文件,然后我们就会发现我们能够通过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];
}12345678910111213141516
效果如下:
正常获取到并且显示,非常棒。
小分享:
GitHub上有很多不错的iOS开源项目,个人认为不错的,有这么几个:
1. ReactiveCocoa:ReactiveCocoa/ReactiveCocoa · GitHub:
GitHub自家的函数式响应式编程范式的Objective-C实现,名字听着很高大上,学习曲线确实也比较陡,但是绝对会改变你对iOS编程的认知,首推之。
2. Mantle:Mantle/Mantle · GitHub:
又是GitHub自家的产物,轻量级建模的首选,也可以很好的配合CoreData工作。
3. AFNetworking:AFNetworking/AFNetworking · GitHub:
iOS7之前,苹果自带的网络库有多难用!matt大神的AFNetworking绝对可以解放你。使用苹果的NSURLRequest及iOS7的NSURLSession,清晰的架构,足够的文档,可以认为是第三方开源库的楷模了。
4. BlocksKit: pandamonia/BlocksKit 路 GitHub
本人相当偏爱Functional Programming,Objective-C中的block绝对满足我的口味。但想用好block也不是很容易,如果对block有爱,就请使用这个库吧。
5. Nimbus:jverkoey/nimbus · GitHub
第一次关注nimbus是因为Facebook的Three20开源库。可惜Three20库已死,主要作者跳出来,写了nimbus。
6. pop: facebook/pop · GitHub
facebook出品的paper,动画效果太好了,赶超apple的原生app一大截。pop就是paper的动画库!
7. GPUImage: BradLarson/GPUImage ยท GitHub
iOS7出来时,很多好看的效果,其实都是对图像的各种处理(比如模糊效果)。图像处理看来以后也是iOS开发的必备技能之一了。而GPUImage,就是能快速处理各种图像效果的利器!
结语如下:
以上就是给Category增添属性的方法啦,不难,只要了解Runtime中的关联对象技术就可以轻松达到了。如果大家还有相关方面的问题,可以登录课课家教育平台咨询~
¥98.00
¥179.00
¥199.00
¥398.00