gpt4 book ai didi

iOS - 后台进程和 UI 更新

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:24:16 24 4
gpt4 key购买 nike

问题很简单:我的应用程序控制每次启动时是否有更新。如果有更新,将显示一个带有是或否选择的弹出窗口。当用户点击是时,4 种方法开始。这些方法下载 xml 文件并上传 CoreData。这是警报的代码:

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {

if (buttonIndex==1) {
[self showActivityViewer];
[self downloadControlAndUpdatePoi];
[self downloadControlAndUpdateItinerari];
[self downloadControlAndUpdateArtisti];
[self downloadControlAndUpdateEventi];
[self hideActivityViewer];
NSLog(@"AGGIORNA");
} else {
NSLog(@"NON AGGIORNARE");
return;
}
}

但是有一个问题:当用户点击是时,警告不会消失并一直显示在屏幕上,直到所有方法都完成。所以我尝试其他代码:

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {

if (buttonIndex==1) {
[self showActivityViewer];
[NSThread detachNewThreadSelector:@selector(startDownloads) toTarget:self withObject:nil];
[self hideActivityViewer];
NSLog(@"AGGIORNA");
} else {
NSLog(@"NON AGGIORNARE");
return;
}
}

-(void)startDownloads {
NSInvocationOperation *opPoi=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdatePoi) object:nil];
NSInvocationOperation *opItinerari=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdateItinerari) object:nil];
NSInvocationOperation *opArtisti=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdateArtisti) object:nil];
NSInvocationOperation *opEventi=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdateEventi) object:nil];
NSArray *operations=[[NSArray alloc] initWithObjects:opPoi,opItinerari,opArtisti,opEventi, nil];
NSOperationQueue *queue=[[NSOperationQueue alloc] init];
[queue addOperations:operations waitUntilFinished:YES];
[queue waitUntilAllOperationsAreFinished];

}

即使在这里也有问题:我点击开始,但事件查看器没有出现。警报消失,线程启动并依次运行 4 个方法。

我需要进程在后台运行,就像我的第二个代码一样,但我什至需要我的 showActityViewer 方法运行并显示微调器。

谢谢:)

最佳答案

要事第一。您不需要启动 4 个操作,因为您已经在辅助线程中并且不需要并行执行 4 个操作。你可以简单地做:

-(void)startDownloads {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[self downloadControlAndUpdatePoi];
[self downloadControlAndUpdateItinerari];
[self downloadControlAndUpdateArtisti];
[self downloadControlAndUpdateEventi];
[pool release];
}

最重要的是,如果你在 downloadControl* 方法中使用 autorelease,你需要在 startDownloads 中定义一个自动释放池,否则我怀疑你会有泄漏。

至于activity indicator为什么不显示,要看你调用的是什么:

    [self hideActivityViewer];

分离后立即。因此,在 UI 有时间 self 更新之前,您正在显示并删除它。从那里删除该行并像这样重写 startDownloads:

-(void)startDownloads {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[self downloadControlAndUpdatePoi];
[self downloadControlAndUpdateItinerari];
[self downloadControlAndUpdateArtisti];
[self downloadControlAndUpdateEventi];
[self performSelectorOnMainThread:@selector(hideActivityViewer) withObject:nil waitUntilDone:NO];

[pool release];
}

这里请注意,我调用主线程来调用hideActivityViewer,因为只有主线程才能安全地使用UIKit。编辑:

我不知道您在下载方法中使用了 Core Data...

看看Concurrency with Core Data .您将需要通过至少为您的辅助线程使用单独的托管对象上下文来稍微调整您的代码(我不知道您是否可以在那里创建 moc)。

另请查看 this tutorial from Cocoa is my Girlfriend .

作为所有这些的替代方案,您可以考虑这样做:

if (buttonIndex==1) {
[self showActivityViewer];
[self performSelector:@selector(startDownloads) withObject:nil afterDelay:0];
NSLog(@"AGGIORNA");
} else {
NSLog(@"NON AGGIORNARE");
return;
}

与:

-(void)startDownloads {
[self downloadControlAndUpdatePoi];
[self downloadControlAndUpdateItinerari];
[self downloadControlAndUpdateArtisti];
[self downloadControlAndUpdateEventi];
[self hideActivityViewer];
}

这根本不使用线程,但我不确定事件查看器是否会正常显示。如果需要,再增加一个级别,您可以在

中指定延迟
[self performSelector:@selector(startDownloads) withObject:nil afterDelay:0.1];

关于iOS - 后台进程和 UI 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6938503/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com