Objective-C 為動態語言,方法調用實為消息發送(objc_msgSend),編譯期不綁定方法地址,因此不存在 C++/Java 意義上的私有方法。但工程上需「內部實現細節不暴露於頭文件」,可通過約定實現準私有效果。
// MyClass.h\
@interface MyClass {\
/* 實例變量 */\
}\
- (void)myPublicMethod;\
@end\
// MyClass.m\
@implementation MyClass\
- (void)myPublicMethod { /* 實現 */ }\
- (void)myPrivateMethod { /* 僅在此實現 */ }\
@end
[obj myPrivateMethod] 調用(編譯警告/錯誤)。[super myPrivateMethod] 或 [self myPrivateMethod] 調用。[obj performSelector:@selector(myPrivateMethod)] 或 objc_msgSend(obj, @selector(myPrivateMethod))。// MyClass.m\
@interface MyClass() // Class Extension,僅在實現文件可見\
- (void)myPrivateMethod;\
@end\
@implementation MyClass\
- (void)myPublicMethod { /* 實現 */ }\
- (void)myPrivateMethod { /* 實現 */ }\
@end
無論採用哪種模式,Objective-C 運行時允許:
// 單參數\ [obj performSelector:@selector(myPrivateMethod)];\ // 多參數\ objc_msgSend(obj, @selector(myPrivateMethod:arg2:arg3), arg1, arg2, arg3);
因此無法在語言層面強制私有,只能靠編碼規範、代碼審查、靜態分析工具約束。
有人提議在 .m 文件頂部定義 static void (^myPrivateBlock)(void) = ^{ ... }; 實現私有邏輯。但 Block 無法捕獲 self(除非手動傳入),已不屬於實例方法範疇,且無法被繼承/多態,實用性極低,不推薦。
理解「動態語言無真私有」的本質,才能在工程中做出務實的封裝決策,避免過度設計或安全幻覺。