一個對象 (委託者) 將特定任務委託給另一個對象 (代理) 執行。iOS 框架大量使用 (UITableViewDelegate, UIScrollViewDelegate 等)。
weak/assign)respondsToSelector: 安全調用可選方法@class Dog; // 前向聲明 @protocol DogToPerson <NSObject> @optional - (void)dogBark:(Dog *)thisDog barkCount:(int)count; @end
// 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
// 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
// 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;
}
weak,MRC 用 assign)@optional + respondsToSelector: 安全調用@class Dog; @protocol DogToPerson; 解決循環引用對於簡單單一回調,Block 更輕量 (參見 Blocks 指南)。代理適合多方法、長生命週期、需標識身份的場景。