如何在不同线程的后台执行某些操作,如果在主线程上执行它会阻止我的应用程序的UI。任何人都知道如何做到这一点?
即使它在后台打印NSLog也没关系。 即使用户按下HOME按钮,我也希望运行以下内容。 在我的viewController中我这样做了:
- (IBAction)btnStartClicked:(UIButton *)sender {
[NSThread detachNewThreadSelector:@selector(StartBGTask) toTarget:self withObject:nil];
}
-(void)StartBGTask{
[[[UIApplication sharedApplication] delegate] performSelector:@selector(startThread)];
}
在appDelegate.m中我有这个方法
-(void) startThread {
@autoreleasepool {
for (int i = 0; i < 100; i++) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"current progress %d", i);
});
[NSThread sleepForTimeInterval:1];
}
}
}
它以1秒的间隔打印1到100之间的整数。
答案 0 :(得分:8)
将这些属性添加到.h文件
@property (nonatomic, strong) NSTimer *updateTimer;
@property (nonatomic) UIBackgroundTaskIdentifier backgroundTask;
现在用这个替换btnStartClicked方法,
-(IBAction)btnStartClicked:(UIButton *)sender {
self.updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:@selector(calculateNextNumber)
userInfo:nil
repeats:YES];
self.backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"Background handler called. Not running background tasks anymore.");
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
}];
}
-(void)calculateNextNumber{
@autoreleasepool {
// this will be executed no matter app is in foreground or background
}
}
如果您需要停止它,请使用此方法,
- (IBAction)btnStopClicked:(UIButton *)sender {
[self.updateTimer invalidate];
self.updateTimer = nil;
if (self.backgroundTask != UIBackgroundTaskInvalid)
{
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
}
i = 0;
}
答案 1 :(得分:6)
检查GCD以获取更多信息。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//code in background
});
答案 2 :(得分:0)
实现目标的一种非常简单的方法:
-(IBAction)btnStartClicked:(UIButton *)sender {
[self performSelectorInBackground:@selector(codeInBakground) withObject:nil];
}
-(void)codeInBakground
{
for (int i = 0; i < 100; i++) {
NSLog(@"current progress %d", i);
[NSThread sleepForTimeInterval:1]; //the code will print one number in each second, until 100
}
}
通过这种方式,您的主线程和UI将不会被阻止。