1. 程式人生 > >Objective-C學習筆記-回撥

Objective-C學習筆記-回撥

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;
}