我希望这不是一个愚蠢的问题,但我需要向用户询问输入,并且需要在与UI异步执行的代码的上下文中。我在幕后与服务器通信,而用户可能正在UI上做其他事情。在通信期间的某个时刻,需要来自用户的输入(诸如密码之类的东西)。
我的问题不在于如何获取信息,我可以使用AlertView或主队列上的某些内容轻松获取信息。对我来说不合适的是将UI代码放入我的模型代码中。我有一个负责网络通信的类,并且从该上下文中实例化UI元素看起来就像是糟糕的设计。
我考虑过使用NSNotificationCenter来广播用户输入或使用委托的需要。问题是,没有特定的ViewController可以作为委托,因为当需要这些信息时,用户可以在任何屏幕上,我不想在每个ViewController中复制通知处理代码。这离开了应用代表。
因此,在iOS开发的世界中,人们通常只是将UI代码留在模型中,或者将代码放在app委托中,还是有其他一些我缺少的设计替代方案?
答案 0 :(得分:2)
委托并不总是必须是对象的实例。它可能只是一个班级!代表中的协议方法必须以" +"让班级回应他们。我确实遇到过你的情况,因为我喜欢保持模型代码(非ui相关)干净。根据您的具体情况,可能还有其他解决方法。
但是,如果有许多对象必须侦听您的事件,那么通知就是解决方案。相反,如果你只需要提供一个输入视图,那么只需要一个委托(你不会有多个viewControllers同时显示输入视图你是不是)。
以下是将类作为委托提供的示例:
[[DatabaseUpdateModel alloc] initWithDelegate: (id)[DatabaseUpdateModelDelegate class]];
并且在DatabaseUpdateModelDelegate.m的实现中,您将拥有例如:
+(void) databaseUpdateModel:(DatabaseUpdateModel*)dbModel didFinishDownloadWithDatabasePath:(NSURL*)path
{
//present UI element to rename database (or whatever the input is for);
}
+(void) databaseUpdateModel:(DatabaseUpdateModel*)dbModel didFaceNetworkError:(NSError*)error
{
//present UI element to notify the user of the error;
}
DatabaseUpdateModel当然不是最好的名字;我只是这样命名就提出了我的观点..
使用这种方法,如果多个对象需要侦听事件,DatabaseUpdateModelDelegate类也可以发出通知。这样你就可以避免你的模型不必要地发送通知(无论是否正在收听)。代表完成所有工作:)
答案 1 :(得分:1)
您可以通过让GUI为模型提供块来将GUI代码与模型代码分离出来,只要执行GUI操作,该模块就会被调用。因此,GUI与模型分离,只是在适当的时候由模型调用。
如果你有一个视图控制器控制器,你可以使用委托或NSNotificationCenter,即一个元视图控制器,它没有与之关联的视图,但管理所有其他视图控制器(如果需要),并可以在顶部显示提示GUI在需要的时候,有什么看法。
答案 2 :(得分:1)
在我看来,您应该使用以下标准:
在这种情况下,使用NSNotification是一个合理的选择,可能会传递用户界面代码的委托,以便在用户输入用户名时使用。密码。请记住,即使用户输入用户名/密码,视图仍应保留在屏幕上,直到网络代码验证完毕。
或者,您可以使用所需的方法公开AppDelegate。这就是我们的工作。例如:
@protocol PasswordViewProtocol
-(void) showPasswordDialog:(NetworkObject*)delegate; // delegate gets called when user hits "Login" with username+password
-(void) hidePasswordDialog; // used if a networking error occurs
-(void) passwordWasIncorrect; // show a red message in the view indicating an error occurred
-(void) passwordWasCorrect; // remove the view, perhaps save the username+password
@end
@interface AppDelegate : UIResponder<UIApplicationDelegate, PasswordViewProtocol>
@end
@interface UIApplication(typedDelegate)
+ (AppDelegate*)typedDelegate;
@end
然后你可以用以下代码调用代码:
[UIApplication.typedDelegate showPasswordDialog:myNetworkObject];
还有很多其他方法可以做同样的事情,但这符合标准。