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

Objective-C 委托模式實戰:牛仔救姑娘完整案例

     編輯:關於C語言

Objective-C 委托模式實戰:牛仔救姑娘完整案例

委托模式是 Objective-C 中核心設計模式,通過協議定義契約,委托對象實現具體行為。本文通過「牛仔救姑娘」的生動故事,完整演示委托模式的設計與實現。

一、核心概念

  • 協議:定義一組方法清單(@required 必須實現,@optional 可選)
  • 委托人:持有符合協議的對象引用,發生事件時調用其方法
  • 被委托人:實現協議方法,處理具體業務邏輯

二、五步實現流程

  1. 定義協議(Wanted)
  2. 委托人類(Girl)聲明 id <Wanted> delegate
  3. 被委托人類(Cowboy)實現協議方法
  4. 設置委托關係:girl.delegate = cowboy
  5. 事件觸發時調用:[delegate saveHerDad]

三、完整代碼實現

1. 協議定義


// Wanted.h
#import <Foundation/Foundation.h>

@protocol Wanted <NSObject>
@required
- (int)saveHerDad;      // 救父親
- (void)killTheBadGuy;  // 殺壞人
@end

2. 委托人:姑娘


// Girl.h
#import <Foundation/Foundation.h>
#import "Wanted.h"

@interface Girl : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) id <Wanted> delegate;
- (instancetype)initWithName:(NSString*)name WithDelegate:(id<Wanted>)delegate;
- (void)helpHelp;  // 觸發求救
@end

// Girl.m
#import "Girl.h"
#import "Cowboy.h"

@interface Girl ()
- (void)seesTheCowboy:(NSTimer *)timer;
@end

@implementation Girl
- (instancetype)initWithName:(NSString*)name WithDelegate:(id<Wanted>)delegate {
    self = [super init];
    if (self) {
        self.name = name;
        self.delegate = delegate;  // 關鍵:設置委托
    }
    return self;
}

- (void)helpHelp {
    NSLog(@"%@: My name is %@, my dad was taken by bad guys, can you save him?", self.name, self.name);
    NSLog(@"%@: OK young lady, wait for good news!", self.delegate);
    // 2秒一次檢查營救進度
    [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(seesTheCowboy:) userInfo:@"My dad" repeats:YES];
}

- (void)seesTheCowboy:(NSTimer *)timer {
    if ([self.delegate respondsToSelector:@selector(saveHerDad)]) {
        int result = [self.delegate saveHerDad];
        if (result == 0) {
            NSLog(@"%@: My heart is broken, you must save him!", self.name);
        } else {
            NSLog(@"%@: Thank you so much, marry me~", self.name);
            [timer invalidate];  // 成功則停止定時器
        }
    }
}
@end

3. 被委托人:牛仔


// Cowboy.h
#import <Foundation/Foundation.h>

@interface Cowboy : NSObject
@property (nonatomic, copy) NSString *name;
@end

// Cowboy.m
#import "Cowboy.h"

@implementation Cowboy
static int result = 0;  // 靜態變量模擬營救進度

- (int)saveHerDad {
    printf("\n");
    result = [self killTheBadGuy];
    if (result == 0) {
        NSLog(@"%@: Too many of them, I'll gather my men!", self.name);
        result++;
        return 0;  // 第一次失敗
    } else {
        NSLog(@"%@ and crew: All bad guys killed, here is your father.", self.name);
        return 1;  // 第二次成功
    }
}

- (int)killTheBadGuy { return result; }

- (NSString *)description { return self.name; }  // 方便NSLog直接輸出名字
@end

4. 主程序啟動


#import <Foundation/Foundation.h>
#import "Girl.h"
#import "Cowboy.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Cowboy *cowboy = [[Cowboy alloc] init];
        cowboy.name = @"John Marston";

        Girl *girl = [[Girl alloc] initWithName:@"Lucy" WithDelegate:cowboy];
        [girl helpHelp];  // 觸發事件

        // 運行 RunLoop 6 秒觀察輸出
        NSDate *date = [NSDate date];
        [[NSRunLoop currentRunLoop] runUntilDate:[date dateByAddingTimeInterval:6]];
    }
    return 0;
}

四、運行輸出


Lucy: My name is Lucy, my dad was taken by bad guys, can you save him?
John Marston: OK young lady, wait for good news!

John Marston: Too many of them, I'll gather my men!
Lucy: My heart is broken, you must save him!

John Marston and crew: All bad guys killed, here is your father.
Lucy: Thank you so much, marry me~

五、關鍵技術點總結

技術點說明
@protocol定義介面契約,編譯期檢查一致性
id <Protocol>聲明符合協議的對象,支持多態
assign vs weakMRC用 assign,ARC用 weak 避免循環引用
respondsToSelector:運行時檢查對象是否實現方法,防崩潰
私有方法實現協議在 .m 中實現,.h 不暴露,封裝內部邏輯
NSTimer + RunLoop模擬異步事件輪詢

六、實戰應用場景

  • UITableViewDataSource / Delegate
  • 網絡請求回調、下載進度回調
  • 自定義視圖事件傳遞(如按鈕點擊、滑動手勢)
  • 模塊解耦:A 模塊定義協議,B 模塊實現,A 持有 B 的協議引用

七、總結

委托模式實現了「關注點分離」:姑娘只管求救,牛仔只管救人,雙方通過協議鬆耦合。這是 Objective-C / Cocoa 開發的靈魂,掌握它等於掌握了 iOS 開發的核心架構思維。

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