首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

Objective-C Protocol 協議完整指南:定義、實作與動態檢查

     編輯:關於C

什麼是 Protocol?

Protocol(協議) 定義了一組方法清單,規範「遵循者」必須或可選實作的介面。它相當於 Java 的 interface 或 C++ 的純虛擬類別,實現「介面與實作分離」,支援多重繼承(一個類別可遵循多個協議)。

協議定義語法

// MyProtocol.h
#import 

// 繼承 NSObject 協議,獲得 retains、description 等基礎方法
@protocol MyProtocol 

@required // 預設區段:必須實作
- (void)requiredMethod;

@optional // 可選區段:視需求實作
- (void)optionalMethodWithArg:(NSInteger)arg;
- (NSInteger)computeResult;

@end

類別遵循與實作協議

// Conformer.h
#import 
#import "MyProtocol.h"

@interface Conformer : NSObject  // 多協議以逗號分隔
- (void)businessLogic;
@end

// Conformer.m
#import "Conformer.h"

@implementation Conformer
- (void)requiredMethod {
    NSLog(@"必須實作的方法");
}
- (void)optionalMethodWithArg:(NSInteger)arg {
    NSLog(@"可選方法,參數=%ld", (long)arg);
}
- (NSInteger)computeResult { return 42; }

// NSCopying 協議要求實作
- (id)copyWithZone:(NSZone *)zone {
    return [[[self class] alloc] init];
}
@end

動態檢查:respondsToSelector: 與 conformsToProtocol:

id obj = [[Conformer alloc] init];

// 1. 檢查具體方法是否實作(針對 @optional)
SEL sel = @selector(optionalMethodWithArg:);
if ([obj respondsToSelector:sel]) {
    [obj performSelector:sel withObject:@(100)];
}

// 2. 檢查類別/物件是否遵循某協議
if ([obj conformsToProtocol:@protocol(MyProtocol)]) {
    NSLog(@"確認遵循 MyProtocol");
}

// 3. 編譯期靜態檢查:id 型別宣告
id protoObj = [[Conformer alloc] init];
[protoObj requiredMethod]; // 編譯器保證存在
// [protoObj nonExistMethod]; // ❌ 編譯警告

實戰範例:簡易插件架構

定義外掛協議

// PluginProtocol.h
@protocol PluginProtocol 
@required
- (NSString *)pluginName;
- (NSString *)version;
- (void)initializeWithConfig:(NSDictionary *)config;
@optional
- (void)onAppEnterBackground;
- (void)onAppWillTerminate;
@end

動態載入與管理

// PluginManager.m
#import "PluginManager.h"
#import "PluginProtocol.h"

@implementation PluginManager {
    NSMutableArray> *_plugins;
}
- (instancetype)init {
    self = [super init];
    if (self) _plugins = [NSMutableArray array];
    return self;
}
- (void)loadPluginClass:(Class)cls withConfig:(NSDictionary *)config {
    if (![cls conformsToProtocol:@protocol(PluginProtocol)]) {
        NSLog(@"%@ 不遵循 PluginProtocol", cls);
        return;
    }
    id plugin = [[cls alloc] init];
    [plugin initializeWithConfig:config];
    [_plugins addObject:plugin];
    NSLog(@"載入外掛: %@ v%@", plugin.pluginName, plugin.version);
}
- (void)notifyEnterBackground {
    for (id p in _plugins) {
        if ([p respondsToSelector:@selector(onAppEnterBackground)]) {
            [p onAppEnterBackground];
        }
    }
}
@end

協議組合與類別擴充

  • 協議繼承:@protocol SubProtocol 形成層級關係。
  • Category 宣告遵循:@interface NSString (JSON) 為現有類別補充協議一致性。
  • Swift 互通:@objc protocol 可被 Swift 類別遵循,反之 Swift protocol 需加 @objc 供 OC 使用。

常見錯誤與最佳實務

  1. 忘記繼承 NSObject 協議:導致 conformsToProtocol:、respondsToSelector: 等根方法不可用,務必寫 @protocol MyProto 。
  2. @optional 方法未檢查直接呼叫:必須配合 respondsToSelector: 防崩潰。
  3. 協議過度膨脹:單一職責原則,拆分為多個小協議(如 DataSource、Delegate、Prefetching)。
  4. 循環引用:Delegate 屬性必須 weak(ARC)或 assign(MRC)。

總結

Protocol 是 Objective-C 實現「面向介面程式設計」的核心機制。掌握 @required/@optional、動態檢查、多協議組合、Category 遵循協議等技巧,能設計出高內聚、低耦合、易測試、支援插件化擴充的架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved