你好,歡迎來到IOS教程網

 Ios教程網 >> IOS訊息 >> 關於IOS >> IOS開發之GCD上異步執行非UI任務

IOS開發之GCD上異步執行非UI任務

編輯:關於IOS

1 前言

如果想要在 GCD 的幫助下能夠異步執行 Non-UI 相關任務。在主隊列、串行隊列和並發隊列上異步執行代碼塊才能見識到 GCD 的真正實力。

要在分派隊列上執行異步任務,你必須使用下面這些函數中的其中一個:

 

dispatch_async

為了異步執行向分派隊列提交一個 Block Object(2 個都通過函數指定);

eg:dispatch_sync(concurrentQueue, printFrom1To1000);

dispatch_async_f

為了異步執行向分派隊列提交一個 C 函數和一個上下文引用(3 項通過函數指定) 。

eg:dispatch_sync_f(concurrentQueue,NULL,printFrom1To1000);

 

2 代碼實例

這節代碼有點多,所以分了兩個工程

First:ZYViewController.m

 

- (void) viewDidAppear:(BOOL)paramAnimated{
//新建一個隊列
dispatch_queue_t concurrentQueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//執行concurrentQueue隊列
dispatch_async(concurrentQueue, ^{
__block UIImage *image = nil;
dispatch_sync(concurrentQueue, ^{
/*下載圖片*/
/* 聲明圖片的路徑*/
NSString *urlAsString = @"http://up.2cto.com/2013/0519/20130519101223949.jpg";
//轉換為NSURL對象
NSURL *url = [NSURL URLWithString:urlAsString]; NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
//聲明NSError對象:一個NSError對象封裝錯誤信息更豐富、更具可擴展性可以只使用一個錯誤代碼和錯誤字符串。
NSError *downloadError = nil;
//獲得對應的Url返回的數據(這裡是一個圖片的數據)
NSData *imageData = [NSURLConnection
sendSynchronousRequest:urlRequest returningResponse:nil error:&downloadError];
if (downloadError == nil &&imageData != nil){
//將NSData轉換為圖片
image = [UIImage imageWithData:imageData]; /* We have the image. We can use it now */
}
else if (downloadError != nil){
NSLog(@"Error happened = %@", downloadError);
}else{
NSLog(@"No data could get downloaded from the URL.");
}
});
dispatch_sync(dispatch_get_main_queue(), ^{
/* 在主線程裡面顯示圖片*/
if (image != nil){
/* 穿件UIImageView視圖 */
UIImageView *imageView = [[UIImageView alloc]
initWithFrame:self.view.bounds];
/* 設置Image */
[imageView setImage:image];
/* 內容適應視圖的大小通過保持長寬比*/
[imageView setContentMode:UIViewContentModeScaleAspectFit];
/* 想Controller View添加圖像視圖 */
[self.view addSubview:imageView];
} else {
NSLog(@"Image isn't downloaded. Nothing to display.");
} });
});
}

- (void) viewDidAppear:(BOOL)paramAnimated{
//新建一個隊列
dispatch_queue_t concurrentQueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//執行concurrentQueue隊列
dispatch_async(concurrentQueue, ^{
__block UIImage *image = nil;
dispatch_sync(concurrentQueue, ^{
/*下載圖片*/
/* 聲明圖片的路徑*/
NSString *urlAsString = @"http://up.2cto.com/2013/0519/20130519101223949.jpg";
//轉換為NSURL對象
NSURL *url = [NSURL URLWithString:urlAsString]; NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
//聲明NSError對象:一個NSError對象封裝錯誤信息更豐富、更具可擴展性可以只使用一個錯誤代碼和錯誤字符串。
NSError *downloadError = nil;
//獲得對應的Url返回的數據(這裡是一個圖片的數據)
NSData *imageData = [NSURLConnection
sendSynchronousRequest:urlRequest returningResponse:nil error:&downloadError];
if (downloadError == nil &&imageData != nil){
//將NSData轉換為圖片
image = [UIImage imageWithData:imageData]; /* We have the image. We can use it now */
}
else if (downloadError != nil){
NSLog(@"Error happened = %@", downloadError);
}else{
NSLog(@"No data could get downloaded from the URL.");
}
});
dispatch_sync(dispatch_get_main_queue(), ^{
/* 在主線程裡面顯示圖片*/
if (image != nil){
/* 穿件UIImageView視圖 */
UIImageView *imageView = [[UIImageView alloc]
initWithFrame:self.view.bounds];
/* 設置Image */
[imageView setImage:image];
/* 內容適應視圖的大小通過保持長寬比*/
[imageView setContentMode:UIViewContentModeScaleAspectFit];
/* 想Controller View添加圖像視圖 */
[self.view addSubview:imageView];
} else {
NSLog(@"Image isn't downloaded. Nothing to display.");
} });
});
}
運行結果

IOS開發之GCD上異步執行非UI任務
Second:

ZYViewController.h

 

#import <UIKit/UIKit.h>

@interface ZYViewController : UIViewController

@property(nonatomic,strong) UILabel *myLabel;

@end

#import <UIKit/UIKit.h>

@interface ZYViewController : UIViewController

@property(nonatomic,strong) UILabel *myLabel;

@end
ZYViewController.m

@synthesize myLabel;

- (void)viewDidLoad
{
[super viewDidLoad];
//聲明一個隊列
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/*
如果我們還沒有保存1000個隨機數在磁盤上,下面的隊列就用來生成這個文件並且用一個Array存放在磁盤上
*/
dispatch_async(concurrentQueue, ^{
NSUInteger numberOfValuesRequired = 10000;
//判斷文件是否存在
if ([self hasFileAlreadyBeenCreated]== NO){
dispatch_sync(concurrentQueue, ^{
//聲明一個可變數組用來存放數值
NSMutableArray *arrayOfRandomNumbers =[[NSMutableArray alloc] initWithCapacity:numberOfValuesRequired];
NSUInteger counter = 0;
for (counter = 0;counter < numberOfValuesRequired;counter++){
//獲得隨機數
unsigned int randomNumber =arc4random() % ((unsigned int)RAND_MAX + 1);
[arrayOfRandomNumbers addObject:[NSNumber numberWithUnsignedInt:randomNumber]];
}
//將這個array寫入到磁盤上
[arrayOfRandomNumbers writeToFile:[self fileLocation] atomically:YES];

});
}
//存放讀取文件內容的數組
__block NSMutableArray *randomNumbers = nil;
//從磁盤上讀取文件並升序排列
dispatch_sync(concurrentQueue, ^{
//如果文件已經被創建,讀取他
if ([self hasFileAlreadyBeenCreated]){
randomNumbers = [[NSMutableArray alloc] initWithContentsOfFile:[self fileLocation]];
/* 排序 */
[randomNumbers sortUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
NSNumber *number1 = (NSNumber *)obj1;
NSNumber *number2 = (NSNumber *)obj2;
return [number1 compare:number2];
}];
}
});
dispatch_async(dispatch_get_main_queue(), ^{
if ([randomNumbers count] > 0){
/* 刷新主線程 */
CGRect labelFrame = CGRectMake(0.0f, 0.0f, 300.0f, 200.0f);
self.myLabel = [[UILabel alloc] initWithFrame:labelFrame];
self.myLabel.numberOfLines = 10;//分10行
NSString *str = [[NSString alloc] initWithFormat:@"RandomNumbers is %@",randomNumbers];//方法一
self.myLabel.text = str;//label的文字
self.myLabel.font = [UIFont boldSystemFontOfSize:14.0f];//字體樣式
self.myLabel.center = self.view.center;//UILabel控件居中
[self.view addSubview:self.myLabel];
}
});
});
}

//獲得文件路徑
-(NSString *)fileLocation{
/*
創建一個列表的目錄搜索路徑。
NSDocumentDirectory:文檔目錄。
NSUserDomainMask:用戶的主目錄的地方,存放用戶的個人項目。
*/
NSArray *folders = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
/* 如果沒有找到返回空 */
if ([folders count] == 0)
{return nil; }
/* 獲得文件路徑的字符串形式 */
NSString *documentsFolder = [folders objectAtIndex:0];
//將文件名追加到foldser後面
return [documentsFolder stringByAppendingPathComponent:@"list.txt"];
}

//判斷文件是否被存在
- (BOOL) hasFileAlreadyBeenCreated{
BOOL result = NO;
//初始化NSFileManager文件管理對象
NSFileManager *fileManager = [[NSFileManager alloc] init];
//判斷文件是否存在
if ([fileManager fileExistsAtPath:[self fileLocation]])
{
result = YES;
}
return result;
}

@synthesize myLabel;

- (void)viewDidLoad
{
[super viewDidLoad];
//聲明一個隊列
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/*
如果我們還沒有保存1000個隨機數在磁盤上,下面的隊列就用來生成這個文件並且用一個Array存放在磁盤上
*/
dispatch_async(concurrentQueue, ^{
NSUInteger numberOfValuesRequired = 10000;
//判斷文件是否存在
if ([self hasFileAlreadyBeenCreated]== NO){
dispatch_sync(concurrentQueue, ^{
//聲明一個可變數組用來存放數值
NSMutableArray *arrayOfRandomNumbers =[[NSMutableArray alloc] initWithCapacity:numberOfValuesRequired];
NSUInteger counter = 0;
for (counter = 0;counter < numberOfValuesRequired;counter++){
//獲得隨機數
unsigned int randomNumber =arc4random() % ((unsigned int)RAND_MAX + 1);
[arrayOfRandomNumbers addObject:[NSNumber numberWithUnsignedInt:randomNumber]];
}
//將這個array寫入到磁盤上
[arrayOfRandomNumbers writeToFile:[self fileLocation] atomically:YES];

});
}
//存放讀取文件內容的數組
__block NSMutableArray *randomNumbers = nil;
//從磁盤上讀取文件並升序排列
dispatch_sync(concurrentQueue, ^{
//如果文件已經被創建,讀取他
if ([self hasFileAlreadyBeenCreated]){
randomNumbers = [[NSMutableArray alloc] initWithContentsOfFile:[self fileLocation]];
/* 排序 */
[randomNumbers sortUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
NSNumber *number1 = (NSNumber *)obj1;
NSNumber *number2 = (NSNumber *)obj2;
return [number1 compare:number2];
}];
}
});
dispatch_async(dispatch_get_main_queue(), ^{
if ([randomNumbers count] > 0){
/* 刷新主線程 */
CGRect labelFrame = CGRectMake(0.0f, 0.0f, 300.0f, 200.0f);
self.myLabel = [[UILabel alloc] initWithFrame:labelFrame];
self.myLabel.numberOfLines = 10;//分10行
NSString *str = [[NSString alloc] initWithFormat:@"RandomNumbers is %@",randomNumbers];//方法一
self.myLabel.text = str;//label的文字
self.myLabel.font = [UIFont boldSystemFontOfSize:14.0f];//字體樣式
self.myLabel.center = self.view.center;//UILabel控件居中
[self.view addSubview:self.myLabel];
}
});
});
}

//獲得文件路徑
-(NSString *)fileLocation{
/*
創建一個列表的目錄搜索路徑。
NSDocumentDirectory:文檔目錄。
NSUserDomainMask:用戶的主目錄的地方,存放用戶的個人項目。
*/
NSArray *folders = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
/* 如果沒有找到返回空 */
if ([folders count] == 0)
{return nil; }
/* 獲得文件路徑的字符串形式 */
NSString *documentsFolder = [folders objectAtIndex:0];
//將文件名追加到foldser後面
return [documentsFolder stringByAppendingPathComponent:@"list.txt"];
}

//判斷文件是否被存在
- (BOOL) hasFileAlreadyBeenCreated{
BOOL result = NO;
//初始化NSFileManager文件管理對象
NSFileManager *fileManager = [[NSFileManager alloc] init];
//判斷文件是否存在
if ([fileManager fileExistsAtPath:[self fileLocation]])
{
result = YES;
}
return result;
}
運行結果

IOS開發之GCD上異步執行非UI任務
 

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved