Category (類別) 允許在不繼承、不修改原類源碼的前提下,為現有類動態添加方法。編譯時合併到類元數據中,運行時無差別調用。
NSString+Encoding.h/m)| 特性 | Category | 繼承 |
|---|---|---|
| 能否添加實例變量 | 不能 | 能 |
| 能否覆蓋現有方法 | 能 (危險,不可控) | 能 (override) |
| 多文件分離編譯 | 支持 | 單一文件 |
| 調用超類實現 | 需通過 runtime | super 直接調用 |
// 為 NSString 添加反轉功能
// 文件名: NSString+ReverseString.h / .m
// .h
@interface NSString (ReverseString)
- (NSString *)reversedString;
@end
// .m
@implementation NSString (ReverseString)
- (NSString *)reversedString {
NSUInteger len = [self length];
unichar buffer[len];
[self getCharacters:buffer range:NSMakeRange(0, len)];
NSMutableString *result = [NSMutableString stringWithCapacity:len];
for (NSInteger i = len-1; i >= 0; i--) {
[result appendFormat:@"%C", buffer[i]]; // %C 輸出 unichar
}
return result;
}
@end
將 Category 聲明與實現放在 同一 .m 文件頂部,外部不可見:
// Foo.m
@interface Foo (Private) // 無對應 .h
- (void)internalHelper;
@end
@implementation Foo (Private)
- (void)internalHelper { NSLog(@"Internal called"); }
@end
@implementation Foo
- (void)publicMethod { [self internalHelper]; } // 僅內部可見
@end
super 實現 (方法列表扁平化)+load 方法在 Category 中會調用,但 +initialize 可能出現多次調用NSArray+SafeAccess)ViewController+Networking)ClassName+Private 於 .m 文件中