Category 允許在**不創建子類**的情況下,為現有類動態添加方法。編譯時期合併到類元數據,運行時無區別。核心限制:**不能添加實例變量 (ivars)**。
// NSString+JSON.h
#import
@interface NSString (JSON)
- (id)jsonObject; // 解析 JSON 字符串
- (BOOL)isValidJSON;
@end
// NSString+JSON.m
#import "NSString+JSON.h"
@implementation NSString (JSON)
- (id)jsonObject {
NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
return [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
}
- (BOOL)isValidJSON {
return [self jsonObject] != nil;
}
@end
// Student.h
@interface Student : NSObject
- (void)study;
@end
// Student 分類
@interface Student (Sports)
- (void)playBasketball;
@end
// Student.m
@implementation Student
- (void)study { NSLog(@"Studying..."); }
@end
@implementation Student (Sports)
- (void)playBasketball { NSLog(@"Playing basketball!"); }
@end
@interface MyClass (Category) { int newVar; } → 編譯錯誤。objc_setAssociatedObject / objc_getAssociatedObject。
myPrefix_methodName。
#import
static const char *KEY = "customProperty";
@implementation NSObject (CustomProperty)
- (void)setCustomProperty:(id)value {
objc_setAssociatedObject(self, KEY, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (id)customProperty {
return objc_getAssociatedObject(self, KEY);
}
@end
關聯策略:OBJC_ASSOCIATION_ASSIGN/RETAIN/COPY × _NONATOMIC/_ATOMIC,對應屬性修飾符。
| 場景 | 例子 | 優勢 |
|---|---|---|
| 系統類擴展 | NSString+JSON, UIColor+Hex, UIView+AutoLayout | 無需繼承、調用語法自然 |
| 大類拆分 | ViewController+Networking, +UISetup, +DataSource | 模塊化、團隊並行開發 |
| 私有方法組織 | ClassName+Private.h/.m | 隱藏實現細節、.h 保持乾淨 |
| 協議實現分離 | ClassName+UITableViewDelegate | 關注點分離、文件結構清晰 |
| 特性 | Category | Extension (匿名分類) |
|---|---|---|
| 語法 | @interface Class (Name) | @interface Class () |
| 可加 ivar | ❌ | ✅ (在 .m 中) |
| 可見性 | 公開 (導入頭文件即可用) | 私有 (僅實現文件可見) |
| 聲明位置 | .h 文件 | .m 文件頂部 |