回調(diào)(callback)就是講一段可執(zhí)行的代碼和一個(gè)特定的事件綁定起來(lái)。當(dāng)特定的事件發(fā)生時(shí),就會(huì)執(zhí)行這段代碼瞬痘。Objective-C中四種途徑可以實(shí)現(xiàn)回調(diào):
- 目標(biāo)-動(dòng)作對(duì)(target-action):在程序開始等待前蒿秦,要求“當(dāng)事件發(fā)生時(shí),向指定的對(duì)象發(fā)生某個(gè)特定的消息”。在這里接收消息的對(duì)象是目標(biāo)(target)西设,消息的選擇器(selector)是動(dòng)作(action)瓣铣。
- 輔助對(duì)象(helper object):在程序開始等待前,要求“當(dāng)事件發(fā)生時(shí)贷揽,向遵守相應(yīng)協(xié)議的輔助對(duì)象發(fā)送消息”棠笑。委托對(duì)象(delegate)和數(shù)據(jù)源(data source)是常見的輔助對(duì)象。
- 通知(notification):即是通知中心(notification center)的對(duì)象擒滑。在程序開始等待前腐晾,可以告知通知中心“某個(gè)對(duì)象正在等待某些特定的通知。當(dāng)其中的某個(gè)通知出現(xiàn)時(shí)丐一,向指定的對(duì)象發(fā)送特定的消息”藻糖。當(dāng)事件發(fā)生時(shí),相關(guān)的對(duì)象會(huì)向通知中心發(fā)布通知库车,然后再由通知中心將通知轉(zhuǎn)發(fā)給正在等待該通知的對(duì)象巨柒。
- Block對(duì)象(Blocks):Block是一段可執(zhí)行的代碼。在程序開始等待前柠衍,聲明一個(gè)Block對(duì)象洋满,當(dāng)事件發(fā)生時(shí),執(zhí)行這段Block對(duì)象珍坊。
事例代碼:
BNRLogger.h
#import <Foundation/Foundation.h>
@interface BNRLogger : NSObject <NSURLConnectionDelegate,NSURLConnectionDataDelegate>
{
NSMutableData *_incomingData;
}
@property (nonatomic) NSDate *lastTime;
-(NSString *) lastTimeString;
-(void)updateLastTime:(NSTimer *)t;
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
-(void)connectionDidFinishLoading:(NSURLConnection *)connection;
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
-(void)zoneChange:(NSNotification *)note;
@end
BNRLogger.m
#import "BNRLogger.h"
@implementation BNRLogger
-(NSString *)lastTimeString
{
static NSDateFormatter *dateFormatter = nil;
if (!dateFormatter) {
dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSLog(@"created dateFormatter");
}
return [dateFormatter stringFromDate:self.lastTime];
}
-(void) updateLastTime:(NSTimer *)t
{
NSDate *now = [NSDate date];
[self setLastTime:now];
NSLog(@"Just set time to %@", self.lastTimeString);
}
//三個(gè)協(xié)議
//收到一定字節(jié)數(shù)的數(shù)據(jù)后會(huì)被調(diào)用
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"received %lu bytes",[data length]);
if (!_incomingData) {
_incomingData = [[NSMutableData alloc]init];
}
[_incomingData appendData:data];
}
//最后一部分?jǐn)?shù)據(jù)處理完畢后會(huì)被調(diào)用
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"Got it all");
NSString *string = [[NSString alloc]initWithData:_incomingData encoding:NSUTF8StringEncoding];
_incomingData = nil;
NSLog(@"String has %lu characters",[string length]);
//如果需要輸出獲取的全部數(shù)據(jù)牺勾,則可以取消下面這行代碼
//NSLog(@"The whole string is %@",string);
}
//獲取數(shù)據(jù)失敗時(shí)會(huì)被調(diào)用
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"connection failed: %@",[error localizedDescription]);
_incomingData = nil;
}
//通知
-(void)zoneChange:(NSNotification *)note
{
NSLog(@"The system time zone has changed!");
}
@end
main.m
#import <Foundation/Foundation.h>
#import "BNRLogger.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
// NSLog(@"Hello, World!");
BNRLogger *logger = [[BNRLogger alloc]init];
//將BNRLogger實(shí)例注冊(cè)為觀察者
[[NSNotificationCenter defaultCenter] addObserver:logger selector:@selector(zoneChange) name:NSSystemTimeZoneDidChangeNotification object:nil];
NSURL *url = [NSURL URLWithString:@"http://www.gutenberg.org/cacahe/epub/205/pg205.txt"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
__unused NSURLConnection *fetchConn = [[NSURLConnection alloc]initWithRequest:request delegate:logger startImmediately:YES];
//未使用變量阵漏,用于消除編譯器警告
__unused NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:logger selector:@selector(updateLastTime:) userInfo:nil repeats:YES];
//運(yùn)行循環(huán)
[[NSRunLoop currentRunLoop] run];
}
return 0;
}