定義於 .m 檔案頂部的 @interface ClassName () 區塊,編譯期可見,執行期合併到主類別。
@property 產生 _ivar)@implementation 中實作所有宣告方法,否則編譯警告// MyClass.m
#import "MyClass.h"
@interface MyClass () // Class Extension
@property (nonatomic, strong) NSString *privateToken;
- (void)internalHelper;
@end
@implementation MyClass
- (void)internalHelper { /* 實作 */ }
@end
建立 ClassName+CategoryName.h/.m,編譯期獨立,執行期動態合併。
xx_myMethod// NSString+Utils.h
@interface NSString (Utils)
- (BOOL)xx_isValidEmail;
@end
// NSString+Utils.m
@implementation NSString (Utils)
- (BOOL)xx_isValidEmail { /* 正則實作 */ return YES; }
@end
| 特性 | Extension | Category | Subclass |
|---|---|---|---|
| 需原始碼 | 是 | 否 | 否 |
| 可加實例變數 | 是 | 否 (用 Associated Objects 替代) | 是 |
| 方法成對象一部分 | 是 | 是 | 否 (僅子類別擁有) |
| 可繼承 | 隨主類別 | 隨主類別 | 是 |
| 適用場景 | 私有介面、框架內部 | 系統類別擴充、模組化功能 | 行為擴充、多態替換 |
協議宣告一組方法簽名,類別宣稱遵循即承諾實作。支援 @required (預設) 與 @optional。
@protocol NetworkDelegate@required - (void)requestDidFinish:(id)response; @optional - (void)requestDidFail:(NSError *)error; - (void)requestProgress:(float)progress; @end // 遵循協議 @interface MyClient : NSObject @end @implementation MyClient - (void)requestDidFinish:(id)response { /* 必須實作 */ } - (void)requestDidFail:(NSError *)error { /* 選擇實作 */ } // 未實作 progress 也合法 @end
「自己不想做的事交給別人做」,解耦發送者與處理者。
// 協議定義 @protocol TaskDelegate- (void)taskDidComplete:(NSString *)result; @end // 發送者 @interface Worker : NSObject @property (nonatomic, weak) id delegate; - (void)startWork; @end @implementation Worker - (void)startWork { // 耗時操作... if ([self.delegate respondsToSelector:@selector(taskDidComplete:)]) { [self.delegate taskDidComplete:@"Success"]; } } @end // 接收者 (ViewController) @interface ViewController () @property (nonatomic, strong) Worker *worker; @end @implementation ViewController - (void)viewDidLoad { self.worker = [Worker new]; self.worker.delegate = self; // 設定代理 [self.worker startWork]; } - (void)taskDidComplete:(NSString *)result { NSLog(@"收到結果: %@", result); } @end
weak 避免循環保留。respondsToSelector: 檢查選擇性方法是否實作。NSObject 可讓 id 直接呼叫 respondsToSelector: 等方法。iOS 4+ 推薦用 Block 簡化單一回呼場景:
typedef void(^CompletionBlock)(NSString *result, NSError *error);
@interface Worker : NSObject
- (void)startWorkWithCompletion:(CompletionBlock)completion;
@end
@implementation Worker
- (void)startWorkWithCompletion:(CompletionBlock)completion {
dispatch_async(dispatch_get_global_queue(0,0), ^{
// 工作...
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) completion(@"Success", nil);
});
});
}
@end
// 使用時注意循環保留
__weak typeof(self) weakSelf = self;
[worker startWorkWithCompletion:^(NSString *result, NSError *error) {
typeof(self) strongSelf = weakSelf;
if (strongSelf) { strongSelf.label.text = result; }
}];
weak 代理屬性防循環。