(1) 用 Xcode 产生的范例程式如下图:
(2) 这个程式在 iPhone 执行的 Livecycle 如下图:
(3) 所谓的 Delegate 是一种 Design Patter,当一个类别,我们想要改变其中部份行为(operation),当然最直接的想法,就是用继承,在子类别(child class),override 一些 methods。
但是有没有其他做法呢?如果我事先不能确定我要修改的类别是谁,我只知道我的对象,跟我已经讲好了协定(protocol),如果我能够满足这个协定,他就把工作交给我,然后我就可以乱搞,这样不是很好?他不用管我是谁,我不用管他是谁,我们只要讲好要如何合作。
这个就是 Delegate。(为何 iPhone SDK 选 Delegate 不选 Sub-class,我个人觉得 delegate 可以动态改变 Host 的行为,另外 delegate 也比较容易实作,且方便管理)。
举个例:
Objective-C 2.0
// A custom view that scrolls its children.
@interface TCScrollView : NSView {
id delegate; // A delegate that wants to act on events in this view
}
-(IBAction)scrollToCenter:(id)sender; // A method that can be bound to a button in the UI
-(void)scrollToPoint:(NSPoint)to;
// Accessors. Implementation not shown.
@property (nonatomic, assign) id delegate;
@end
// This is a formal protocol: implementor doesn't have to implement all or even any of
// the optional methods in the protocol
@protocol TCScrollViewDelegate
@optional
-(BOOL)scrollView:(TCScrollView*)scrollView shouldScrollToPoint:(NSPoint)newPoint;
@end
@implementation TCScrollView
-(IBAction)scrollToCenter:(id)sender; {
[self scrollToPoint:NSPointMake(0,0)];
}
-(void)scrollToPoint:(NSPoint)to {
BOOL shouldScroll = YES;
// If we have a delegate, and that delegate indeed does implement our delegate method,
if(delegate && [delegate respondsToSelector:@selector(scrollView:shouldScrollToPoint:)])
shouldScroll = [delegate scrollView:self shouldScrollToPoint:to]; // ask it if it's okay to scroll to this point.
// If not, ignore the scroll request.
if(!shouldScroll)
return;
// Scrolling code omitted.
}
@end
@interface MyCoolAppController : NSObject {
IBOutlet TCScrollView* scrollView;
}
@end
@implementation MyCoolAppController
-(void)awakeFromNib {
[scrollView setDelegate:self];
}
-(BOOL)scrollView:(TCScrollView*)scrollView shouldScrollToPoint:(NSPoint)newPoint {
if(newPoint.x > 0 && newPoint.y > 0)
return YES;
return NO;
}
@end
[edit]