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

Objective-C 代理模式 完整實戰:協議定義、委託傳遞與定時器回調示例

     編輯:關於C語言

代理模式核心思想

一個對象 (委託者) 將特定任務委託給另一個對象 (代理) 執行。iOS 框架大量使用 (UITableViewDelegate, UIScrollViewDelegate 等)。

  • 委託者持有代理弱引用 (weak/assign)
  • 代理遵循協議實現回調方法
  • 運行時通過 respondsToSelector: 安全調用可選方法

完整示例:Dog (委託者) 與 Person (代理)

1. 定義協議 (DogToPerson.h)

@class Dog; // 前向聲明
@protocol DogToPerson <NSObject>
@optional
- (void)dogBark:(Dog *)thisDog barkCount:(int)count;
@end

2. 委託者 Dog 類

// Dog.h
#import "DogToPerson.h"
@interface Dog : NSObject
@property (assign) int dogID;
@property (weak) id<DogToPerson> delegate; // 弱引用防循環
- (instancetype)initWithID:(int)id;
@end

// Dog.m
#import "Dog.h"
@implementation Dog {
    NSTimer *timer;
    int barkCount;
}
- (instancetype)initWithID:(int)id {
    self = [super init];
    if (self) {
        _dogID = id;
        barkCount = 0;
        timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(timerFire:) userInfo:nil repeats:YES];
    }
    return self;
}
- (void)timerFire:(NSTimer *)timer {
    barkCount++;
    if ([self.delegate respondsToSelector:@selector(dogBark:barkCount:)]) {
        [self.delegate dogBark:self barkCount:barkCount];
    }
}
- (void)dealloc { [timer invalidate]; }
@end

3. 代理 Person 類

// Person.h
#import "Dog.h"
@interface Person : NSObject <DogToPerson>
@property (strong) Dog *dog;
@end

// Person.m
#import "Person.h"
@implementation Person
- (void)dogBark:(Dog *)thisDog barkCount:(int)count {
    NSLog(@"Person: Dog %d barked %d times", thisDog.dogID, count);
}
@end

4. 主程序綁定並運行 RunLoop

// main.m
#import "Person.h"
#import "Dog.h"
int main() {
    @autoreleasepool {
        Person *xiaoLi = [[Person alloc] init];
        Dog *dog1 = [[Dog alloc] initWithID:1024];
        dog1.delegate = xiaoLi; // 設置代理
        xiaoLi.dog = dog1;      // 可選:反向持有
        // 保持 RunLoop 運行以接收定時器事件
        [[NSRunLoop currentRunLoop] run];
    }
    return 0;
}

關鍵點總結

  1. 協議分離:協議獨立頭文件,降低耦合
  2. 弱引用 delegate:防止循環保留 (ARC 下用 weak,MRC 用 assign)
  3. 可選方法:@optional + respondsToSelector: 安全調用
  4. 前向聲明:@class Dog; @protocol DogToPerson; 解決循環引用
  5. RunLoop:主線程需運行 RunLoop 處理定時器/網絡事件

擴展:Block 回調替代代理

對於簡單單一回調,Block 更輕量 (參見 Blocks 指南)。代理適合多方法、長生命週期、需標識身份的場景。

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