iPHone:我们使用MonoTouch,但Obj-C答案还可以。
我的单例域对象需要一段时间才能获取所有数据,因此它在内部运行部分线程中的fetch。
我需要通知UI域已完成。目前我这样做。有没有更好的办法?在WinForms中,我将调用Application.DoEvents()而不是Thread Sleep。
PlanDomain domain = PlanDomain.Instance ();
while (domain.IsLoadingData)
{
Thread.Sleep (100); //this is the main UI thread
}
TableView.Hidden = false;
TableView.Source = new TableSource (this);
TableView.ReloadData ();
答案 0 :(得分:6)
关于休息室回答的跟进,这是一个C#代码示例:
NSRunLoop.Current.RunUntil(DateTime.Now.AddMilliseconds(2000));
这将暂停2000毫秒,但确保UI更新。我只是在一些测试代码中使用它。
答案 1 :(得分:3)
一般来说,你想避免使用DoEvents。在objective-c中的iPhone等价物看起来像这样:
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]];
答案 2 :(得分:2)
除非你想进行后台加载,否则从AlertView(加载对话框)派生的东西会更好。
然后,在您加入的单独Thread
中运行任务,然后关闭对话框。有一个示例here,但没有任何线程,但是添加它是微不足道的:
public class LoadingView : UIAlertView
{
private UIActivityIndicatorView _activityView;
public void Show(string title)
{
Title = title;
Show();
// Spinner - add after Show() or we have no Bounds.
_activityView = new UIActivityIndicatorView(UIActivityIndicatorViewStyle.WhiteLarge);
_activityView.Frame = new RectangleF((Bounds.Width / 2) - 15, Bounds.Height - 50, 30, 30);
_activityView.StartAnimating();
AddSubview(_activityView);
// I haven't tested this, it should display the dialog still.
Thread thread = new Thread(DoWork);
thread.Start();
thread.Join();
Hide();
}
private void DoWork()
{
PlanDomain domain = PlanDomain.Instance ();
while (domain.IsLoadingData)
{
// Maybe replace domain.IsLoadingData with an Event for when it finishes.
// And then use a Mutex (WaitHandle) to communicate back
}
}
public void Hide()
{
DismissWithClickedButtonIndex(0, true);
}
}
答案 3 :(得分:1)
我看看你是否可以使用performSelectorOnMainThread:将你的Tableview代码移动到它自己的方法,并在你完成加载数据时回调它。
代理在这种情况下也很有用 - 让PlanDomain在完成后回调到委托函数。
同样地,如果你想要更多分离的东西,请看看使用NSNotification。当你编写的代码不需要知道或关心它完成后会发生什么时,这些是最有用的 - 它只需要向全世界宣布它完成了它的工作。 (最有用的地方可能有多件事情可能会在完成时采取行动。
在其中任何一个中,你都不想睡觉 - 只需让runloop处理它。