是下面的代码,我正在使用printerArray = [SMPort searchPrinter];加载数据。这是一个昂贵的操作,并锁定ui。是否有一种异步方式这样我就可以显示一个加载指示符,并且当它完成时显示数据?
//
// SearchPrinterViewController.m
// PHP POS
//
// Created by Chris Muench on 3/12/14.
// Copyright (c) 2014 PHP Point Of Sale. All rights reserved.
//
#import "PrintingViewController.h"
#import "StarIO/SMPort.h"
#import "PrinterFunctions.h"
@interface PrintingViewController ()
@end
@implementation PrintingViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
uitableview_printerList.dataSource = self;
uitableview_printerList.delegate = self;
//Expensive operation. Could take up to 3-5 seconds
printerArray = [SMPort searchPrinter];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return printerArray.count + 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if (indexPath.row < printerArray.count)
{
PortInfo *port = [printerArray objectAtIndex:indexPath.row];
cell.textLabel.text = port.modelName;
NSString *detailText = [NSString stringWithFormat:@"%@(%@)", port.portName, port.macAddress];
cell.detailTextLabel.text = detailText;
}
else if (indexPath.row == printerArray.count)
{
cell.textLabel.text = @"Back";
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row < printerArray.count)
{
PortInfo *portInfo = [printerArray objectAtIndex:indexPath.row];
[PrinterFunctions PrintPHPPOSDocumentWithPortName:portInfo.portName textToPrint:self.textToPrint portSettings:@""];
}
[self dismissViewControllerAnimated:YES completion:nil];
}
@end发布于 2014-03-14 16:20:18
// This sends the fetching operation on the background
// You can put a loading indicator HERE BEFORE the dispatch.
// This sends the fetching operation on the background
[SVProgressHUD showWithStatus:@"Finding Printers" maskType:SVProgressHUDMaskTypeBlack];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
printerArray = [SMPort searchPrinter];
// Here you send tell the main thread to reload the table
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss];
[uitableview_printerList reloadData];
});
});当然还有很多其他的解决方案,但在我看来,对于你的情况来说,这是最起码的一种解决方案。
编辑:我忘记了一件事:为了使printerArray在块中可写,在声明时必须在前面添加关键字__block。
编辑:我把最后的工作代码。我不需要添加__block来做一些准备。
发布于 2014-03-14 16:27:41
您可以使用第二个NSOperationQueue或GCD (大中央调度)。上文对全球荒漠化办法作了说明。下面是NSOperation队列方法:
NSOperationQueue *printQueue = [[NSOperationQueue alloc] init];
[printQueue addOperationWithBlock:^{
// Background work
NSArray * array = [SMPort searchPrinter];
// Update the UI (in the main queue)
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
printerArray = [array copy];
[uitableview_printerList reloadData];
}];
}];看一下这段视频:
https://developer.apple.com/videos/wwdc/2012/index.php?id=211
本教程是:
http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues
https://stackoverflow.com/questions/22410450
复制相似问题