我试图了解类别的实际用法,而不是Objective-C中的继承。我什么时候应该选择使用类别?使用代码的真实示例会很有帮助。
答案 0 :(得分:3)
当您需要向现有类添加功能时。
例如,您的应用正在使用NSDate
或NSString
个实例,并且您想要添加一些功能。您无法将功能添加到子类,因为您无法强制系统方法返回子类。
只需查看API中的示例:
1 / NSDictionary用于保存文件属性,并具有返回文件大小的方法
2 / NSString
有一个用绘图扩展它的UI类别。请注意,您不希望可以绘制单独的字符串子类。您希望所有字符串都能够被绘制。
答案 1 :(得分:2)
当我需要添加一些方便的函数时,我会使用类别,我将重复使用这些函数到现有的类,而不需要子类来覆盖该类的某些现有函数。
例如,当我想检查空字符串,或删除字符串的所有前导和尾随空格时:
.h文件:
@interface NSString (Extension)
-(BOOL)isEmptyString;
-(NSString *)trimLeadingAndTrailingWhiteSpaces;
@end
.m文件:
@implementation NSString (Extension)
-(BOOL)isEmptyString
{
NSString *myString = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if (myString.length == 0)
return TRUE;
else
return FALSE;
}
-(NSString *)trimLeadingAndTrailingWhiteSpaces
{
NSString *myString = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
return myString;
}
@end
使用它:
someString = [someString trimLeadingAndTrailingWhiteSpaces];
if ([someString isEmptyString])
{
//someString is empty, do whatever!
}
答案 2 :(得分:1)
我认为类别是实现继承提供的某些功能的一种更简单的方法。继承不提供其他类别的事项。类别允许您扩展现有类的功能,而无需对其进行子类化。您还可以使用它们来替换类中的现有方法。与指向原始类的后代的子类不同,类别方法有点用螺栓固定到现有类上。一旦将类别方法添加到目标c类,它就可用于该类的所有实例,包括那些不是由您创建的实例。
例如,如果您需要对项目中的所有数据使用加密函数,并说大多数数据仅使用NString进行保存和操作。您可以采用的方法之一是为NSString创建一个类别
的NSString-Encryption.h
@interface NSString (Encryption)
-(NSString*) encrypt;
@end
NSString-Encryption.m
#import "NSString-Encryption.h"
@implementation NSString (Encryption)
-(NSString*) encrypt
{
// your encryption method here
return encryptedString;
}
@end
使用NSString-encryption.m
NSString *testString = @"this is test";
NSString *encryptedString = [testString encrypt];
正如您所看到的,该类别比子类更容易使用。这个方法也可以从NSMutableString调用,因为它继承自NSString。所以它很强大。
您还可以使用category替换类上的现有方法。
类别的另一个用途是它可以用于私有方法,因为目标c没有方法的正式私有名称。这是通过将类别放在.m文件而不是.h文件中完成的。
Phone.h
@interface Phone:NSObject
-(void) call;
@end
Phone.m
@interface Phone(Private)
-(void) validatePhoneEntry:(NSString*) phoneNumber;
@end
@implementation Phone
-(void) validatePhoneEntry:(NSString*) phoneNumber
{
}
-(void) call
{
}
@end
类别的缺点是,如果需要将成员变量添加到类中,则无法使用它们。
答案 3 :(得分:0)
答案 4 :(得分:0)
如果要将添加方法添加到类中,请使用类别。如果要更改类中现有方法的功能,请创建子类。
有点/ sorta可以使用类别来替换现有方法,有点像覆盖子类,但不应该使用类别。原因有三:1)您无法访问原始方法; 2)你不会破坏现有的代码; 3)如果多个类别试图“覆盖”同一个方法,那么该类最终的方法是未定义的。基本上,类最终将使用应用于类的最后一个类别的方法,但不能依赖应用类别的顺序。这是乱七八糟的食谱,所以就是不要这样做。
因此,您可以使用类别向NSData添加方法,例如+(NSData*)dataWithCryptographicallyRandomBytes:(NSUInteger)length
或-(void)base64Decode
。但是如果你想改变现有方法的行为,比如-writeToFile:atomically:
,你应该创建一个NSData的子类并在那里实现你的新功能。首先,您可能仍希望使用覆盖中的现有行为,并且子类化允许您通过调用[super writeToFile:file atmoically:YES]
来执行此操作。此外,在这里使用子类意味着您的新行为只会影响您自己的代码 - 它不会影响在框架中其他地方使用NSData,而不会期望您的新功能。
答案 5 :(得分:0)
类别类似于Java接口(在java中,实现不是可选的) - 一种对方法进行分组并使对象响应特定API的方法 - 独立于类类型。如果你需要添加额外的ivars并且新类与isa关系匹配(student isa person),则继承是有意义的。添加一些实用程序方法并不是一个例子 - 这通常是通过协议完成的。类别通常与代理一起使用,其中有问题的方法是可选的。