以下是代码,我使用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
答案 0 :(得分:2)
// 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];
});
});
当然还有很多其他解决方案,但对我而言,这似乎是最小的解决方案。
编辑: 我忘记了一件事:为了使printArray在块中可写,你必须在声明它时在前面添加关键字 __ block 。
编辑:我把最终的工作代码。我不需要为某些reaosn添加__block。答案 1 :(得分:0)
您可以使用第二个NSOperationQueue或GCD(Grand Central Dispatch)。 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