下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

Category是什么以及怎么创建Category

作者:课课家教育     来源: http://www.kokojia.com点击数:2638发布时间: 2017-04-09 08:40:28

标签: iOS移动开发大数据

     了解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:

Category是什么以及怎么创建Category_iOS_移动开发_大数据_课课家教育

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

在出来的界面中的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

  效果如下:

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

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

  小分享:

  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中的关联对象技术就可以轻松达到了。如果大家还有相关方面的问题,可以登录课课家教育平台咨询~

赞(23)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程