Class extension vs class category
类扩展@interface Class ()更强大,可以向类中注入变量。类别@interface Class (Category)不能。
还有什么其他的区别,什么时候应该在类扩展上使用类别?
- 类别是实际代码。它们是你如何将特性添加到类中的。扩展(在非常一般的术语中)更只是语法上的糖分,向其他程序员发出关于隐私等某些想法的信号。扩展不包含代码,也不是代码。
- 对于在swift中使用的扩展,请参见以下问题:stackoverflow.com/questions/24142829/…
主要区别在于,对于扩展,编译器希望您在主@implementation中实现方法,而对于类别,您有一个单独的@implementation块。所以您应该只在主.m文件的顶部使用一个扩展名(顺便说一下,这是您唯一应该关注ivar的地方)--它的意思就是,一个扩展名。
- 但是,在类别上使用扩展有什么意义呢?
- 扩展最适合于要在.m文件中声明的私有方法。我一直用它来做这个。当您希望将方法分组到不同的部分(类别:)或希望向未创建的现有类添加代码时,类别更有用。
- 还可以使用属性添加附加存储IS类扩展。
- 类扩展还专门设计为允许公开的readonly和私人的readwrite。不能对类别(有意识的设计选择)这样做。
- 为什么谷歌使用类别来实现私有方法而不是扩展?例如code.google.com/p/gdata objectiec client/source/browse/trun‌&8203;k/…
- 扩展需要在@implementation块中实现所有方法,还提供了变量增强功能。但我们基本上是想把一些私有方法放在这里,而不是使用私有变量,所以在这种情况下,我们更喜欢类别而不是扩展
- 还应该注意的是,只能为具有源代码的类编写扩展。相反,您可以将类别应用于任何系统类。值得注意的是,您可以通过objc_getassociatedobject和objc_setassociatedobject运行时函数在类别中实现新属性的外观。
- 您还可以使用类扩展使私有方法对其他类(如测试用例)可见。只需将类扩展添加到测试类并重新声明该方法。
- @你什么意思?1。我不能为系统类Ex nsObject编写扩展吗(我没有nsObject的源代码)?
- @iosdeveloper:您可能在考虑子类,但是可以在这里找到完整的解释,搜索"类扩展与类别有一些相似之处,但是它只能添加到编译时有源代码的类中…"。
- @这就是你的意思吗?stackoverflow.com/questions/4837565/…如果没有,请举例说明。
- 如果它是私有的,那么为什么我需要在我的@interface中放置一个函数?!移除它会失去什么?或者,对于功能来说,它没有提供任何好处,只对添加私有IVAR有用吗?
- 这是我问题的答案吗?
- 一次修正。在实现基于框架的代码时,类扩展被专门设计来帮助支持API的"公共的、私有的、内部的"特性。也就是说,你把你的主@interface放在class.h中,你的"只应该由共享的内部使用"放在Class_Private.h的扩展中,真正的内部垃圾放在Class_Internal.h或class.m中,并使用xcode的头可见性检查器设置头文件的公开程度。
类扩展与类别有一些相似之处,但它只能添加到编译时具有源代码的类中(类与类扩展同时编译)。类扩展声明的方法在原始类的@implementation块中实现,因此,例如,您不能在框架类(如cocoa或cocoa touch类,如nsstring)上声明类扩展。
声明类扩展的语法与类别的语法类似,如下所示:
1 2
| @interface ClassName ()
@end |
因为括号中没有名字,类扩展通常被称为匿名类。
与常规类别不同,类扩展可以向类添加自己的属性和实例变量。如果在类扩展中声明属性,如:
1 2 3 4 5
| @interface XYZAnimal () {
id _someCustomInstanceVariable;
}
...
@end |
imho,最好把类扩展看作类的私有接口。主接口(在.h文件中)充当公共接口,用于定义类与其他类的行为契约。
使用类扩展来隐藏私有信息
类扩展通常用于使用附加的私有方法或属性扩展公共接口,以便在类本身的实现中使用。例如,通常在接口中将属性定义为只读,但在实现上方声明的类扩展中定义为读写,以便类的内部方法可以直接更改属性值。
例如,XYZPerson类可能会添加一个名为UniqueIdentifier的属性,用于跟踪信息,如美国的社会保险号。
它通常需要大量的文书工作才能为现实世界中的某个人分配唯一标识符,因此XYZPerson类接口可能会将此属性声明为只读,并提供一些方法来请求分配标识符,如:
1 2 3 4 5
| @interface XYZPerson : NSObject
...
@property (readonly) NSString *uniqueIdentifier;
- (void)assignUniqueIdentifier;
@end |
为了让XYZPerson类能够在内部更改属性,有必要在类的实现文件顶部定义的类扩展名中重新声明该属性:
1
| @property (readwrite) NSString *uniqueIdentifier; |
注意:readwrite属性是可选的,因为它是默认的。为了清晰起见,您可能希望在重新定义属性时使用它。
类别是一个客观的C语言特性,允许您向现有类添加新方法。扩展是类别的一种特殊情况,允许您定义必须在主实现块中实现的方法。
私有声明可以在类扩展中,这主要是一些属性,因为我们在调用方法之前不需要声明它。
- "必须在主实现块中声明。"->必须在主实现块中"实现"
- 谢谢,我已经修改过了。
iOS扩展到C语言,Java抽象类或接口< BR>iOS类别类似于C类扩展
- Java不支持扩展方法
- 对不起的!复制粘贴错误。iOS类别类似于C类扩展。