使用NSOperation为你的app加速
app store中的很多應用程序非常的笨重,他們有好的界面,但操作性很差,比如說當程序從網上或本地載入數據的時候,界面被凍結了,用戶只能等程序完全載入數據之后才能進行操作。
當打開一個應用程序時,iphone會產生一個包含main方法的線程,所用程序中的界面都是運行在這個線程之中的(table views, tab bars, alerts…),有時候我們會用數據填充這些view,現在問題是如何有效的載入數據,并且用戶還能自如的操作程序。
下面要說方法的并不是要在用戶載入數據的時候在界面上提示“loading”的信息,雖然這種方式在有些時候是可以被接受的,但當數據在main線程之外被載入是并不是最有效的方式。
先看一下要演示的程序:
這個程序將從網絡上下載10,000條數據,并填入到UITableView中,現面的代碼將首先演示一種錯誤的方式:
錯誤 (源碼 )
| ? @implementationRootViewController @synthesizearray;-(void)viewDidLoad {[super viewDidLoad];/* Adding the button */self.navigationItem.rightBarButtonItem =[[UIBarButtonItem alloc]initWithTitle:@"Load"style:UIBarButtonItemStyleDone target:selfaction:@selector(loadData)];/* Initialize our array */NSMutableArray*_array =[[NSMutableArrayalloc]initWithCapacity:10000]; self.array=_array; [_array release]; }// Fires when the user presses the load button-(void)loadData {/* Grab web data */NSURL*dataURL =[NSURLURLWithString:@"http://icodeblog.com/samples/nsoperation/data.plist"];NSArray*tmp_array =[NSArrayarrayWithContentsOfURL:dataURL];/* Populate our array with the web data */for(NSString*str intmp_array){[self.arrayaddObject:str]; }/* reload the table */[self.tableViewreloadData]; }#pragma mark Table view methods-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{return1; }-(NSInteger)tableView:(UITableView *)tableViewnumberOfRowsInSection:(NSInteger)section {return[self.arraycount]; }-(UITableViewCell *)tableView:(UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath {staticNSString*CellIdentifier =@"Cell";UITableViewCell *cell=[tableViewdequeueReusableCellWithIdentifier:CellIdentifier]; if(cell==nil){cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]autorelease]; }/* Display the text of the array */[cell.textLabel setText:[self.arrayobjectAtIndex:indexPath.row]];returncell; }-(void)dealloc{[super dealloc]; [arrayrelease]; }@end |
當點擊“load”按鈕時程序會被凍結,直到將數據完全下載并填入Tableview,在這期間用戶不能做任何的事情。
在給出解決方式之前先來看一下NSOperationQueue和NSOperation:
下面要做的是建立NSOperationQueue和NSOperations。NSOperationQueue會建立一個線程,每個加入到線程operation會有序的執行。
下面是使用NSOperationQueue的過程:
使用NSOperation有幾種,現在介紹最簡單的一種NSInvocationOperation,NSInvocationOperation是NSOperation的子類,允許運行在operation中的targer和selector。??下面是執行NSInvocationOperation的一個例子:
| ? NSOperationQueue*queue =[NSOperationQueuenew];NSInvocationOperation*operation=[[NSInvocationOperationalloc]initWithTarget:selfselector:@selector(methodToCall)object:objectToPassToMethod];[queue addOperation:operation]; [operationrelease]; |
下面是我們用正確的方式實現的程序:
正確的方式(下載源碼 )
| ? @implementationRootViewController @synthesizearray;-(void)viewDidLoad {[super viewDidLoad];self.navigationItem.rightBarButtonItem =[[UIBarButtonItem alloc]initWithTitle:@"Load"style:UIBarButtonItemStyleDonetarget:selfaction:@selector(loadData)];NSMutableArray*_array =[[NSMutableArrayalloc]initWithCapacity:10000];self.array=_array;[_array release]; }-(void)loadData {/* Operation Queue init (autorelease) */NSOperationQueue*queue =[NSOperationQueuenew];/* Create our NSInvocationOperation to call loadDataWithOperation, passing in nil */NSInvocationOperation*operation=[[NSInvocationOperationalloc]initWithTarget:selfselector:@selector(loadDataWithOperation)object:nil];/* Add the operation to the queue */[queue addOperation:operation];[operationrelease]; }-(void)loadDataWithOperation {NSURL*dataURL =[NSURLURLWithString:@"http://icodeblog.com/samples/nsoperation/data.plist"];NSArray*tmp_array =[NSArrayarrayWithContentsOfURL:dataURL];for(NSString*str intmp_array){[self.arrayaddObject:str];}[self.tableViewreloadData]; }#pragma mark Table view methods-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{return1; }-(NSInteger)tableView:(UITableView *)tableViewnumberOfRowsInSection:(NSInteger)section {return[self.arraycount]; }-(UITableViewCell *)tableView:(UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath {staticNSString*CellIdentifier =@"Cell";UITableViewCell *cell=[tableViewdequeueReusableCellWithIdentifier:CellIdentifier];if(cell==nil){cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]autorelease];}[cell.textLabel setText:[self.arrayobjectAtIndex:indexPath.row]];returncell; }-(void)dealloc{[super dealloc];[arrayrelease]; } |
再次運行程序,當點擊“load”按鈕時界面是否還被“凍結”呢,程序并沒有增加很多的代碼,但確大大的提高了用戶體驗。
轉載于:https://www.cnblogs.com/zhwl/archive/2013/01/05/2845281.html
總結
以上是生活随笔為你收集整理的使用NSOperation为你的app加速的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU 3397 线段树 双懒惰标记
- 下一篇: Git 上传文件到 码云 gitee