Objective-C學習筆記-回撥
阿新 • • 發佈:2018-12-11
1.OC中有四種方法實現回撥,分別是目標-動作對,輔助物件,通知,Block物件
2.目標-動作對,是指當某個事件發生時,向指定物件傳送指定訊息,計時器使用的就是目標-動作對機制,如下程式碼所示,每隔兩秒會執行一次updateLastTime方法,其中NSRunLoop用來保持執行緒允許並處理事件
- (void)updateLastTime:(NSTimer *)t{ NSLog(@"timer is %@",t); } #import <Foundation/Foundation.h> #import "MyDesktop.h" int main(int argc, const char * argv[]) { @autoreleasepool { MyDesktop *desktop=[[MyDesktop alloc] init]; __unused NSTimer *timer=[NSTimer scheduledTimerWithTimeInterval:2.0 target:desktop selector:@selector(updateLastTime:) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] run]; } return 0; }
3.輔助物件,是指當某個事件發生時,根據協議(可以理解為Java裡的Interface)向輔助物件傳送訊息,所以輔助物件必須實現要求的協議才能接受訊息
//宣告 @interface MyDesktop : NSObject<NSURLConnectionDelegate,NSURLConnectionDataDelegate> @end //實現 @implementation MyDesktop - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ NSLog(@"recevive data size is %ld",[data length]); } - (void)connectionDidFinishLoading:(NSURLConnection *)connection{ NSLog(@"Got it all"); } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ NSLog(@"%@",[error localizedDescription]); } @end int main(int argc, const char * argv[]) { @autoreleasepool { MyDesktop *desktop=[[MyDesktop alloc] init]; NSURL *url=[NSURL URLWithString:@"http://www.baidu.com"]; NSURLRequest *request=[NSURLRequest requestWithURL:url]; __unused NSURLConnection *coon=[[NSURLConnection alloc] initWithRequest:request delegate:desktop startImmediately:YES]; [[NSRunLoop currentRunLoop] run]; } return 0; }
4.通知,蘋果公司提供了一種稱為通知中心的物件,可以通過通知中心等待某個通知出現時,向指定的物件傳送指定的訊息,下面是監聽系統時區改變的程式碼
@interface MyDesktop : NSObject -(void)zoneChanged:(NSNotification *)note; @end @implementation MyDesktop -(void)zoneChanged:(NSNotification *)note{ NSLog(@"zone changed!"); } @end int main(int argc, const char * argv[]) { @autoreleasepool { MyDesktop *desktop=[[MyDesktop alloc] init]; [[NSNotificationCenter defaultCenter] addObserver:desktop selector:@selector(zoneChanged:) name:NSSystemTimeZoneDidChangeNotification object:nil]; [[NSRunLoop currentRunLoop] run]; } return 0; }
5.Block物件有點像Java裡的匿名函式,C裡面的函式指標,使用時要注意以下兩點
- Block物件中使用外部變數是隻讀的,如果想修改外部變數,需要在外部變數前面加上__block修飾
- Block物件使用外部變數時,會持有它們(強引用),所以要避免造成強引用迴圈
int main(int argc, const char * argv[]) {
@autoreleasepool {
MyDesktop *desktop=[[MyDesktop alloc] init];
//弱引用
__weak MyDesktop *weakDesktop=desktop;
//賦值
[desktop setHeight:222];
void (^MyBlock)(NSString *,NSUInteger);
MyBlock=^(NSString * str,NSUInteger value){
//避免物件被釋放
MyDesktop *innerDesktop=weakDesktop;
NSLog(str,innerDesktop.height+value);
};
MyBlock(@"test value is %ld",1111);
}
return 0;
}