我正在开发一个iPhone应用程序,它执行了一个耗时操作,我想创建一个activityIndicator来告知用户应用程序没有冻结。
该操作完全在一个事件调用中执行...因此UI框架没有机会接收控制以显示和动画化这个指示器。
使用UIActivityIndicator(或任何其他类似动画)的示例应用程序在不同的事件中启动和停止动画,分别在程序的不同阶段触发。
我需要手动创建一个单独的线程来运行我的操作吗?还是已经默认支持这种行为?
我正在开发一个iPhone应用程序,它执行了一个耗时操作,我想创建一个activityIndicator来告知用户应用程序没有冻结。
该操作完全在一个事件调用中执行...因此UI框架没有机会接收控制以显示和动画化这个指示器。
使用UIActivityIndicator(或任何其他类似动画)的示例应用程序在不同的事件中启动和停止动画,分别在程序的不同阶段触发。
我需要手动创建一个单独的线程来运行我的操作吗?还是已经默认支持这种行为?
我刚刚在苹果iPhone论坛上找到了一个很相似的问题,并得到了一个好答案。
https://devforums.apple.com/message/24220#24220基本上,是的,你需要在不同的线程中启动你的进程,但这很容易做到(来自用户 'eskimo1' 的转述)。
- (IBAction)syncOnThreadAction:(id)sender
{
[self willStartJob];
id myObject = [MyObjectClass createNewObject];
[self performSelectorInBackground:
@selector(inThreadStartDoJob:)
withObject:myObject
];
}
- (void)inThreadStartDoJob:(id)theJobToDo
{
NSAutoreleasePool * pool;
NSString * status;
pool = [[NSAutoreleasePool alloc] init];
assert(pool != nil);
status = [theJobToDo countGrainsOfSandOnBeach];
[self performSelectorOnMainThread:
@selector(didStopJobWithStatus:)
withObject:status
waitUntilDone:NO
];
[pool drain];
}
这里的-willStartJob
和-didStopJobWithStatus
是我自己定义的方法,它们会:
如果您想执行应该在主线程上启动的操作,那么启动新线程可能会过度杀伤和增加复杂性。
在我的代码中,我需要通过按下按钮来启动MailComposer,但是它可能需要一些时间才能出现,我希望同时确保UIActivityIndicator正在旋转。
这是我的做法:
-(void)submit_Clicked:(id)event
{
[self.spinner startAnimating];
[self performSelector:@selector(displayComposerSheet)
withObject:nil afterDelay:0];
}
哪个更容易:
1> Have 1 method that starts the spinner (in the background).
2> Run your long-running code right here.
3> Have 1 method that ends the spinner.
或者...
A> Have 1 method that starts the spinner.
B> Have 20 methods (1 for each thing you want to do in the background)
C> Have 1 method that ends the spinner.
我总是看到大家都建议用A、B、C...的困难方式。