iOS基础---Category vs Extension

打印 上一主题 下一主题

主题 1012|帖子 1012|积分 3036

系列文章目录

iOS基础—Block
iOS基础—Protocol
iOS基础—KVC vs KVO
iOS网络—AFNetworking
iOS网络—NSURLSession
iOS内存管理—MRC vs ARC
iOS基础—Category vs Extension
iOS基础—多线程:GCD、NSThread、NSOperation
iOS基础—常用三方库:Masonry、SDWebImage
iOS基础—定时器:GCD、NSTimer、CADisplayLink

  

一、Category

1.Category是什么

   Category(类别)是Objective-C 2.0之后添加的语言特性,允许开发者在不修改原有类的情况下,为其添加新的方法。Category 特殊实用于扩展系统类和第三方类的功能。
  我们在利用Xcode 创建文件时,可以将 File Type 指定为 Category,Class指定为我们要举行扩展的类:

然后就会自动天生 Person+Student.h 和 Person+Student.m 文件:

2. 利用场景

利用 Category 的好处是:
   

  • 分离代码逻辑
    Category 可以将一个类的实现分成多个独立的部门,每个部门专注于差别的功能或逻辑。这使得代码更易于管理和维护。
  • 扩展现有类
    Category 允许你为现有的类添加新功能,而无需子类化或修改原始类的代码。这对于扩展系统类(如 NSString, NSArray 等)尤其有效。
  • 组织代码
    通过利用 Category,可以将相关的方法组织在一起,使代码更加模块化和易读。比方,可以为一个复杂的视图控制器创建多个 Category,每个 Category 处理视图控制器的差别方面。
  • 简化代码重用
    Category 允许你在多个类中重用相同的代码,而无需复制粘贴。这对于通用的工具方法或功能特殊有效。
  • 动态加载功能
    Category 可以在运行时动态加载功能,这使得它们非常恰当插件系统或模块化应用。
  如果我们创建一个 MacOs 的 Command Line Tool 程序用 Category 对类举行扩展,会报错:
   /Applications/code_test/category_test/main.m:17:14 No visible @interface for ‘Person’ declares the selector ‘PrintNameTwice’
  这是由于 Command Line Tool 程序中函数的调用是编译时确定的,而 Category 是 Runtime 时加载的,以是我们创建一个 App 程序举行实行:


3.注意事项

分类只能增加方法,不能增加成员变量。

分类中的方法如果与原类的方法名相同,大概会覆盖原类的方法。

可以添加属性声明,但不能直接实现属性的存取方法(getter 和 setter)。关联对象(Associated Objects)是一种机制,允许为现有对象动态添加属性。它们利用 objc_setAssociatedObjectobjc_getAssociatedObject 函数来设置和获取值。
   在Objective-C中,属性(Property)通常由实例变量(Instance Variables)和访问方法(Getter和Setter)构成。当你在类的声明中添加一个属性时,编译器会自动天生相应的实例变量和访问方法。然而,在Category中,编译器无法为其添加实例变量,由于Category并不改变类的内存结构。
  


objc_setAssociatedObjectobjc_getAssociatedObject 的函数原型:
  1. void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
  2. //object: 需要关联值的对象。
  3. //key: 用于唯一标识关联的键,通常使用静态地址或唯一的指针。
  4. //value: 要关联的值,可以是任何对象。如果传入 nil,则会移除先前关联的值。
  5. //policy: 关联策略,定义了关联对象的内存管理语义。
  6. OBJC_ASSOCIATION_ASSIGN:指定一个弱引用关联对象,不保留新的值。
  7. OBJC_ASSOCIATION_RETAIN_NONATOMIC:指定关联对象的强引用,且不使用原子操作。
  8. OBJC_ASSOCIATION_COPY_NONATOMIC:指定关联对象的副本,且不使用原子操作。
  9. OBJC_ASSOCIATION_RETAIN:指定关联对象的强引用,使用原子操作。
  10. OBJC_ASSOCIATION_COPY:指定关联对象的副本,使用原子操作。
  11. id objc_getAssociatedObject(id object, const void *key);
  12. //object: 需要获取关联值的对象。
  13. //key: 用于唯一标识关联的键,这个键必须与 objc_setAssociatedObject 时使用的键相同。
复制代码
对于原理,美团技能团队已经做了深入的解说:深入理解Objective-C:Category
二、Extension

   在 iOS 开发中,类扩展(Class Extension)是一种用于在类的实现文件中声明私有方法和属性的机制。与 Category 差别,类扩展只能在类的实现文件中利用,而且必须在编译时确定。类扩展通常用于声明类的私有接口,隐藏实现细节,增强封装性。
  类扩展的用途:


  • 声明私有属性:在类扩展中声明的属性只能在类的实现文件中访问。
  • 声明私有方法:在类扩展中声明的方法只能在类的实现文件中调用。
  • 提供更好的封装:通过将私有接口隐藏在实现文件中,类扩展进步了代码的封装性。
下面是一段在 MyClass.m 文件中对 MyClass 类举行扩展的代码:
  1. // MyClass.m
  2. #import "MyClass.h"
  3. @interface MyClass ()
  4. @property (nonatomic, strong) NSString *privateProperty; // 私有属性
  5. - (void)privateMethod;// 私有方法
  6. @end
  7. @implementation MyClass
  8. - (void)privateMethod {
  9.     NSLog(@"Private Property: %@", self.privateProperty);
  10. }
  11. @end
复制代码
三、对比


  • 用途差别
   

  • Category
  

  • 用于为现有类添加方法,而不需要修改原始类的代码。
  • 可以在任何地方定义和利用。
  • 主要用于将类的功能模块化、分离代码逻辑,或者为系统类添加新功能。
  

  • Extension
  

  • 用于在类的实现文件中声明私有属性和方法。
  • 只能在类的实现文件中利用。
  • 主要用于隐藏实现细节,增强类的封装性。
  

  • 添加内容的差别
   

  • Category:
  

  • 只能添加方法,不能添加实例变量(成员变量)。
  • 可以添加属性声明,但不能直接实现属性的存取方法(getter 和 setter)。
  

  • Extension:
  

  • 可以添加方法和实例变量(成员变量)。
  • 可以添加属性,而且可以在实现文件中实现属性的存取方法。
  

  • 编译时 vs 运行时
   

  • Category:
  

  • 在运行时加载,可以动态地为类添加方法。
  • 方法的加载次序大概影响方法的覆盖(如果多个 Category 添加了相同的方法)。
  

  • Extension:
  

  • 在编译时确定,必须在类的实现文件中定义。
  • 由于是在编译时确定的,类扩展中的方法和属性与类的其他部门一样被处理。
  

  • 可见性
   

  • Category:
  

  • 方法是公共的(public),可以被任何地方访问。
  • 实用于对外扩展类的功能。
  

  • Extension:
  

  • 方法和属性是私有的(private),只能在类的实现文件中访问。
  • 实用于隐藏实现细节,增强封装性。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

络腮胡菲菲

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表