在ClassA内:
-(void)authenticateUser
{
authenticate_Obj = [classB_Obj authenticateMobileUser];
}
Inside ClassB:
-(AuthenticateObj*)authenticateMobileUser
{
[mobile_Obj AuthenticateMobileServer:self action:@selector(Handler:)];
return authenticate_G_Obj;
}
-(void)Handler:(id)value
{
authenticate_G_Obj = (AuthenticateObj*)value;
}
现在,当classB的authenticateMobileUser方法将控件返回给ClassA时,我们将启动Object authenticate_Obj。
我的问题是,当我运行项目时,authenticate_Obj为NULL ...实际上当它进入处理程序方法时,Object被初始化。但是受控制返回到ClassA,而不进入Handler方法。我想这是异步执行的问题。 如何让它进入处理程序方法,然后只将控件返回到ClassA ??
Plz帮帮我......
谢谢。
答案 0 :(得分:2)
听起来您想要做的就是阻止执行,直到身份验证完成为止。如果AuthenticateMobileServer
产生后台线程可以使用,那么可能可能 - 您使用同步对象,例如NSLock - 但这确实是一个坏主意。如果你要阻止,为什么还有一个后台线程呢?如果你不知道你正在做什么,那么线程同步是非常棘手的并且容易出错,而你(不管怎么说)你不知道。
相反,您可能应该接受在身份验证发生时存在一段时间的不确定性,在此期间您的应用应保持处理处于某种中间状态,然后使用回调通知您当身份验证完成后,您可以继续使用经过身份验证的用户所需的任何操作。
有很多方法可以做到这一点,而且问题中没有足够的细节来确切地说哪个最好。但是你似乎已经在ClassB
内使用了非常相似的内容,所以我要说ClassA
做同样的事情:
Inside ClassA:
-(void)authenticateUser
{
authenticate_Obj = nil;
[classB_Obj authenticateMobileUserAndNotify:self action:@selector(authenticatedObject:)];
// returns more or less immediately, not yet authenticated
}
-(void)authenticatedObject:(YourAuthObjectClass*) authObj
{
authenticate_Obj = authObj;
// do post-authentication stuff here
}
Inside ClassB:
-(void)authenticateMobileUserAndNotify:(id)target action:(SEL)sel
{
// I'm making these ivars for simplicity, there might be other considerations though
callbackTarget = target;
callbackSelector = sel;
[mobile_Obj AuthenticateMobileServer:self action:@selector(Handler:)];
}
-(void)Handler:(id)value
{
authenticate_G_Obj = (AuthenticateObj*)value;
[callbackTarget performSelectorOnMainThread:callbackSelector withObject:authenticate_G_Obj waitUntilDone:NO];
}
显然,这只是一个草图,并不打算按原样使用。并且您需要考虑处于等待状态的应用中发生了什么,身份验证正在进行中,但authenticate_Obj
仍为nil
。但希望你明白了。
答案 1 :(得分:0)
我认为你是说AuthenticateMobileServer:action:
是异步的,你想要阻止它直到它完成所以你可以获得返回值。不幸的是,我们无法在不知道它是如何工作的情况下告诉你。主要问题是它是在主线程还是辅助线程上运行Handler操作。
如果它在主线程上运行操作,最好的策略是立即从authenticateMobileUser
返回,而不等待身份验证对象并禁用依赖于身份验证的UI元素。然后,当您获得身份验证对象时,您应该重新启用UI元素。
如果它在后台线程上运行操作,最简单的方法是设置另一个类似于Handler的方法(顺便提一下,方法和变量的命名约定是从小写开始),然后从中调用处理程序performSelectorOnMainThread:waitUntilDone:
。然后,您可以使用与上述相同的策略。
答案 2 :(得分:0)
JeremyP和walkytalky的答案都是正确的,并且是创建响应式UI的核心。经验法则:
如果你在主线程上进行潜在的阻塞操作,例如联网,你就会遇到麻烦。
至少有两个原因:
所以为了完成这项工作,可能需要一些时间,你必须在后台线程上完成。正如JeremyP和walkytalky的两个答案经常指出的那样,你会得到一个回调。这很好,但总共有三种消息传递方式:
这三种都可以使用。它们之间存在细微差别。其中最重要的一点是,委托是1:1的消息传递,而另一种是1:n消息传递。
现在说不要认为你必须使用NSThread。请看一下NSOperation和NSOperationQueue。它们允许在操作中封装多个工作,并让它们在后台运行。此外,如果您使用@selector(methodname :)语法的这些回调,还有一些新的:块。通常有一些等效方法可以将块而不是选择器作为回调来执行。
完成这里是黄金法则:
您可以在后台线程上更新您的模型,但不要在后台线程上更新您的UI。
查看有关这些主题的WWDC10视频。关于网络的讨论很有两个部分,详细解释了这些概念。