iOS開發之Block實現同非同步載入
一. 相關知識
1.控制層
負責資料的互動.控制層請求資料,會建立一個具有網路請求的對象.對象中有一個block,block會將請求到的資料回調給控制層.
2.資料的傳輸過程
Request(請求到資料後) 回調給Controller
二. 資料同步載入
思想:
Request對象負責下載網路資料.Controller中需要下載的資料,但直接在Controller中實現下載功能,不是一種好的習慣.採取在Request中實現下載功能,同時設定block屬性,將下載資料回調給Controller(前提是Controller中實現了block).在Controller中定義一個Request對象,負責下載資料.資料下載後,會執行block,而block是在Controller中實現的,故下載資料可以Controller中使用.
Request.h //資料請求 負責載入資料 通過block將載入資訊回調給Controller
#import @interface Request : NSObject//data負責儲存請求的資料 error 負責儲存操作失誤的資訊 目的 功能設計的方便使用//功能失敗時給使用者提供失敗資訊@property (nonatomic, copy) void(^block)(NSData * data, NSError * error);//網路下載方法- (void)requestDataFromUrl:(NSString *) url;@end
Requset.m
#import Request.h@implementation Request@synthesize block = _block;- (void)dealloc{ [_block release]; [super dealloc];}- (void)requestDataFromUrl:(NSString *)url { //網路地址 NSURL * URL = [NSURL URLWithString:url]; //通過網路地址下載資料 NSData * data = [NSData dataWithContentsOfURL:URL]; //通過block將資料返回 @try { //正常的資料請求 //1.請求的資料不為空白 //2.請求的本身就是空的 if (nil != data) { //通過調用block 將資料正常返回 self.block(data, nil); } else { //給予資料為空白的提示 NSError * error = [[NSError alloc] initWithDomain:@請求到得資料為空白 code:404 userInfo:nil]; self.block(nil, error); [error autorelease]; } } @catch (NSException *exception) { //網路請求失敗時 //exception 拋出異常 當網路請求本身就不成功時 裡麵包含了操作失敗 NSError * error = (NSError *)exception; self.block(nil, error); }}@end
Controller.h
#import Controlller.h#import Request.h@implementation Controlller { Request * _request;}- (void)viewDidLoadWithURL:(NSString *)url { //給網路屬性賦值 _request = [[Request alloc] init]; //做好回調資料的接受準備 //1.建立block 2.讓request block指向建立的block _request.block = ^(NSData * data, NSError * error) { if (nil != data) { NSString * str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@%@, str); [str release]; } else { NSLog(@%@, error.localizedDescription); } }; [_request requestDataFromUrl:url];}- (void)dealloc{ [_request release]; [super dealloc];}@end
Controller.m
#import Controlller.h#import Request.h@implementation Controlller { Request * _request;}- (void)viewDidLoadWithURL:(NSString *)url { //給網路屬性賦值 _request = [[Request alloc] init]; //做好回調資料的接受準備 //1.建立block 2.讓request block指向建立的block _request.block = ^(NSData * data, NSError * error) { if (nil != data) { NSString * str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@%@, str); [str release]; } else { NSLog(@%@, error.localizedDescription); } }; [_request requestDataFromUrl:url];}- (void)dealloc{ [_request release]; [super dealloc];}@end
主函數
#import #import Controlller.h#define URL @http://Mrshang110.local/Demo/1.txtint main(int argc, const char * argv[]) { @autoreleasepool { //建立對象 Controlller * ctr = [[Controlller alloc] init]; //調用介面 [ctr viewDidLoadWithURL:URL]; [ctr release]; } return 0;}
三. 非同步載入
#import #import Controller.h#define URL @http://Mrshang110.local/Demo/1.txtint main(int argc, const char * argv[]) { @autoreleasepool { Controller * ctr = [[Controller alloc] init]; [ctr viewDidLoadWithUrl:URL]; [ctr release]; sleep(1); } return 0;}#import @interface Controller : NSObject- (void)viewDidLoadWithUrl:(NSString *)url;@end#import Controller.h#import Request.h@implementation Controller { Request * _request;}- (void)viewDidLoadWithUrl:(NSString *)url { if (nil == _request) { _request = [[Request alloc] init]; } _request.block = ^(NSData * data, NSError * error) { if (nil != data) { NSString * str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@%@, str); [str release]; } else { NSLog(@%@, error.localizedDescription); } }; [_request requestDataWithUrl:url];}- (void)dealloc{ [_request release]; [super dealloc];}@end#import @interface Request : NSObject@property (nonatomic,copy) void(^block)(NSData * data, NSError * error);//聲明一個方法用於資料下載- (void)requestDataWithUrl:(NSString *)url;@end#import Request.h@implementation Request@synthesize block = _block;- (void)requestDataWithUrl:(NSString *)url { NSURL * URL = [NSURL URLWithString:url]; //建立分線程去請求資料 資料請求完回到主線程 //NSThread 線程類 其對象是一個分線程 分線程可以從主線程獨立出來 將結果通知主線程 //主線程 和 分線程同時執行 NSThread * thread = [[NSThread alloc] initWithTarget:self selector:@selector(download:) object:URL]; //download 是一個帶參數的方法 其網路請求下固定為URL //建立分線程thread 去執行當前類的對象方法download //目的 分線程中下載資料 /* 啟 動 分 線 程 */ [thread start];}- (void)download:(NSURL *)url { //分線程需要執行的代碼 //建立NSData 儲存下載數 NSData * data = [NSData dataWithContentsOfURL:url]; //處理請求到的資料 @try { //正常的資料返回 if (nil != data) { self.block(data, nil); } else { NSError * error = [[NSError alloc] initWithDomain:@請求資料為空白 code:404 userInfo:nil]; self.block(nil, error); } } @catch (NSException *exception) { //網路請求本身錯誤時 NSError * error = (NSError *)exception; self.block(nil, error); }}- (void)dealloc{ [_block release]; [super dealloc];}@end