iOS 四種回調方法總結_IOS

來源:互聯網
上載者:User

最近對做IOS 項目遇到回調,抽空把相關資料整理下,以下是整理內容:

回調

回調就是將一段可執行檔代碼和一個特定的事件綁定起來。當特定的事件發生時,就會執行這段代碼。
在Objective-C中,有四條途徑可以實現回調。

目標-動作對

在程式開始定等待前,要求“當時間發生時,向指定的對象發送某個特定的資訊”。這裡接收訊息的對象是目標,訊息的選取器是動作。

輔助對象

在程式開始等待之前,要求“當時間發生時,向遵守相應協議的輔助對象發送訊息”。委派物件和資料來源是常見的輔助對象。

通知

蘋果公司提供了一種稱為通知中樞的對象。在程式開始等待前,就可以告知通知中樞”某個對象正在等待某些特定的通知。當其中的某個通知出現時,向指定的對象發送特定的訊息”。當事件發生時,相關的對象會向通知中樞發布通知,然後再由通知中樞將通知轉寄給正在等待通知的對象。

Block對象

Block是一段可執行代碼。在程式開始等待前,聲明一個Block對象,當事件發生時,執行這段Block對象。

NSRunLoop

iOS中有一個NSRunLoop類,NSRunLoop執行個體會持續等待著,當特定的事件發生時,就會向相應的對象發送訊息。NSRunLoop執行個體會在特定的事件發生時觸發回調。

迴圈

實現回調之前要先建立一個迴圈:

int main(int argc, const char * argv[]) {  @autoreleasepool {    [[NSRunLoop currentRunLoop]run];  }  return 0;}

目標-動作對

建立一個擁有NSRunLoop對象和NSTimer對象的應用程式。每隔兩秒,NSTimer對象會向其目標發送指定的動作訊息,建立一個新的類,名為BNRLogger,為NSTimer對象的目標。
在BNRLogger.h中聲明動作方法:

#import <Foundation/Foundation.h>@interface BNRLogger : NSObject<NSURLSessionDataDelegate>@property(nonatomic) NSDate *lastTime;-(NSString *) lastTimeString;-(void)updateLastTime: (NSTimer *) t;@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);}@end

main.m中建立一個BNRLogger執行個體:

#import <Foundation/Foundation.h>#import "BNRLogger.h"int main(int argc, const char * argv[]) {  @autoreleasepool {    BNRLogger *logger=[[BNRLogger alloc]init];    __unused NSTimer *timer=[NSTimer scheduledTimerWithTimeInterval:2.0 target:logger selector:@selector(updateLastTime:) userInfo:nil repeats:YES];    [[NSRunLoop currentRunLoop]run];  }  return 0;}

輔助對象

我的上一篇Blog已經寫過NSURLSession方法的使用,那麼輔助對象回調的使用,將BNRLogger對象成為NSURLSession的委派物件,特定的事件發生時,該對象會向輔助對象發送訊息。
main.m中建立一個NSURL對象以及NSURLRequest對象。然後建立一個NSURLSession對象,設定BNRLogger的執行個體為它的

委派物件:

#import <Foundation/Foundation.h>#import "BNRLogger.h"int main(int argc, const char * argv[]) {  @autoreleasepool {    BNRLogger *logger=[[BNRLogger alloc]init];    //URL是一張圖片的下載連結    NSURL *url = [NSURL URLWithString:@"yun_qi_img/error.html&thumburl=http%3A%2F%2Fimg4.imgtn.bdimg.com%2Fit%2Fu%3D2349180720%2C2436282788%26fm%3D11%26gp%3D0.jpg"];    NSURLRequest *request = [NSURLRequest requestWithURL:url];    __unused NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:logger delegateQueue:[NSOperationQueue mainQueue]];    __unused NSTimer *timer=[NSTimer scheduledTimerWithTimeInterval:2.0 target:logger selector:@selector(updateLastTime:) userInfo:nil repeats:YES];    //4.根據會話對象建立一個Task(發送請求)    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];    //5.執行任務    [dataTask resume];    [[NSRunLoop currentRunLoop]run];  }  return 0;}

BNRLogger.h中,聲明NSURLSessionDataDelegate協議:

#import <Foundation/Foundation.h>@interface BNRLogger : NSObject<NSURLSessionDataDelegate>@property (nonatomic, strong) NSMutableData *responseData;@property(nonatomic) NSDate *lastTime;-(NSString *) lastTimeString;-(void)updateLastTime: (NSTimer *) t;@end

BNRLogger.m中,有NSURLSession的代理方法,具體可以看NSURLSession:

#import "BNRLogger.h"@implementation BNRLogger-(NSMutableData *)responseData{  if (_responseData == nil) {    _responseData = [NSMutableData data];  }  return _responseData;}-(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);}//1.接收到伺服器響應的時候調用該方法-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{  //在該方法中可以得到回應標頭資訊,即response  NSLog(@"didReceiveResponse--%@",[NSThread currentThread]);  NSLog(@"響應");  //注意:需要使用completionHandler回調告訴系統應該如何處理伺服器返回的資料  //預設是取消的  /*   NSURLSessionResponseCancel = 0,    預設的處理方式,取消   NSURLSessionResponseAllow = 1,     接收伺服器返回的資料   NSURLSessionResponseBecomeDownload = 2,變成一個下載請求   NSURLSessionResponseBecomeStream    變成一個流   */  completionHandler(NSURLSessionResponseAllow);}//2.接收到伺服器返回資料的時候會調用該方法,如果資料較大那麼該方法可能會調用多次-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{  NSLog(@"didReceiveData--%@",[NSThread currentThread]);  NSLog(@"返回");  //拼接伺服器返回的資料  [self.responseData appendData:data];}//3.當請求完成(成功|失敗)的時候會調用該方法,如果請求失敗,則error有值-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{  NSLog(@"didCompleteWithError--%@",[NSThread currentThread]);  NSLog(@"完成");  if(error == nil)  {    //解析資料    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:nil];    NSLog(@"%@",dict);  }}@end

通知

當系統時區發生變化時,會向通知中樞發布NSSystemTimeZoneDidChangeNotification通知,然後通知中樞會將該通知轉寄給相應的觀察者。

main.m中將BNRLogger執行個體註冊為觀察者,系統時區設定發生變化可以收到相應的通知:

 //在”輔助對象”方法應用程式中的main.m中加入這行代碼 [[NSNotificationCenter defaultCenter]addObserver:logger selector:@selector(zoneChange:) name:NSSystemTimeZoneDidChangeNotification object:nil];

在BNRLogger.m中實現該方法:

 //在”輔助對象”方法應用程式中的BNRLogger.m中加入這行代碼 -(void)zoneChange:(NSNotification *)note{  NSLog(@"The system time zone has changed!");}

Block回調

把上面所講的“通知”方法應用程式main.m中的:

[[NSNotificationCenter defaultCenter]addObserver:logger selector:@selector(zoneChange:) name:NSSystemTimeZoneDidChangeNotification object:nil];

改為:

[[NSNotificationCenter defaultCenter]addObserverForName:NSSystemTimeZoneDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note){      NSLog(@"The system time zone has changed!");    }];

“通知”方法應用程式BNRLogger.m中的這個方法去掉:

-(void)zoneChange:(NSNotification *)note{  NSLog(@"The system time zone has changed!");}

總結

  1. 對於只做一件事情的對象(例如),使用目標-動作對。
  2. 對於功能更複雜的對象(例如NSURLSession),使用輔助對象。最常見的輔助物件類型是委派物件。
  3. 對於要觸發多個(其他對象中的)回調的對象(例如NSTimeZone),使用通知。
  4. Block實現回調使代碼便於閱讀。

感謝閱讀,希望能協助到大家,謝謝大家對本站的支援!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.