首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS Category(類別)三大用途詳解:私有方法前向引用的實戰演示

     編輯:程式設計綜合問答

Category 三大核心用途

  1. 分散實現/擴展無源碼類:將庞大類拆分到多文件,或為系統類(如 NSString、UIView)添加方法。
  2. 私有方法前向引用:在編譯期消除「未找到方法」警告,實現對私有方法的調用。
  3. 非正式協議:定義一組可選方法,作為委托回調接口(早期 @protocol 不支持可選方法時的替代方案)。

重點解析:私有方法前向引用

問題場景

類 Person 在 .m 文件的 @interface Person() 擴展中聲明了私有方法 getName。外部類直接調用 [Person getName] 會編譯報錯:No known class method for selector 'getName'。

Category 解決方案

// Person+Private.h
#import "Person.h"
@interface Person (Private)
+ (void)getName; // 僅聲明,無需實現
@end

在調用處 #import "Person+Private.h" 後,編譯器知曉 getName 存在,不再報錯。運行時動態綁定會找到 Person.m 中的實際實現並執行。

完整演示代碼

// Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
+ (void)getAge;
@end

// Person.m
#import "Person.h"
@interface Person ()
+ (void)getName; // 私有方法聲明
@end
@implementation Person
+ (void)getAge { NSLog(@"age:18"); }
+ (void)getName { NSLog(@"name:XXX"); }
@end

// Person+Private.h (Category)
#import "Person.h"
@interface Person (Private)
+ (void)getName; // 前向引用聲明
@end

// Caller.m
#import "Person+Private.h"
@implementation Caller
- (void)test {
    [Person getName]; // 不再報錯,運行輸出 "name:XXX"
}
@end

注意事項

  • Category 不能添加實例變量(可用關聯對象 objc_setAssociatedObject 模擬)。
  • 方法名衝突:若 Category 和主類/其他 Category 同名方法,調用行為未定義(通常 Category 優先),建議加前綴如 xxx_getName。
  • 私有方法調用屬於「破壞封裝」,僅限調試、Hook、適配舊代碼等場景,常規開發應暴露公共接口。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved