在今天之前 如果有人问我 如果给NSString添加一个方法 ,我最先想到的方法肯定就是使用Category。一直觉得NSString是不能被继承的,因为它是类簇,其实如果真的想继承,也是有办法的。
在Cocoa框架里有许多类簇,比如NSArray,NSString,NSNumber(具体什么是类簇就不解释了。网上关于类簇的介绍很多)。在这里我就把今天看到的《Effective Objective-C 2.0》中关于如何如果继承类簇介绍一下。
具体关于如何为类簇添加子类,需要遵守几条规则:
- 子类应该继承自类簇中的抽象基类。
- 子类应该自定义自己的数据存储方式。(开发者编写NSArray子类时,必须用一个实例变量来存放数组中的对象。这似乎与大家预想的不同,我们以为NSArray自己肯定会保存那些对象,所以在子类中就无须再保存一份了。但是大家要记住,NSArray本身只不过是包在其他隐藏对象外面的壳,它仅仅定义了所有数组都需具备的一些接口。对于这个自定义的数组类来说,可以用NSArray来保存其实例)。
- 子类应当覆写超类文档中指明需要覆写的方法。
接下来就动手实现如何继承NSArray 和 NSString。
#import "WUArray.h"
@interface WUArray()
{
NSArray *_storeArray;
}
@end
@implementation WUArray
- (instancetype)initWithArray:(NSArray *)array {
if (self = [super init]) {
_storeArray = [NSArray arrayWithArray:array];
}
return self;
}
#pragma mark - override
- (NSUInteger)count {
return _storeArray.count;
}
- (id)objectAtIndex:(NSUInteger)index {
return [_storeArray objectAtIndex:index];
}
@end
以上为WUArray.m文件
#import "WUString.h"
@interface WUString()
{
NSString *_storeString;
}
@end
@implementation WUString
- (instancetype)initWithString:(NSString *)aString {
if (self = [self init]) {
_storeString = [[NSString stringWithString:aString] copy];
}
return self;
}
- (NSUInteger)length {
return [_storeString length];
}
- (unichar)characterAtIndex:(NSUInteger)index {
return [_storeString characterAtIndex:index];
}
@end
以上为WUString.m 文件
实现完之后 来验证一下:
WUString *str = [[WUString alloc] initWithString:@"123456789"];
NSLog(@"%@",[str substringFromIndex:5]); //控制台打印输出为 6789
WUArray *array = [[WUArray alloc] initWithArray:@[@"h",@"e",@"l",@"l",@"0"]];
NSLog(@"%@",[array componentsJoinedByString:@"."]); //控制台打印输出为 h.e.l.l.o
在继承的时候 关于要具体覆写超类的哪几个方法,NSString的头文件里面写的有:
/* NSString primitives. A minimal subclass of NSString just needs to implement these two, along with an init method appropriate for that subclass. We also recommend overriding getCharacters:range: for performance.
*/
@property (readonly) NSUInteger length;
- (unichar)characterAtIndex:(NSUInteger)index;