当我们有两个在层次结构中非常深的 UIViewControllers 并且它们都需要保存状态的相同依赖项时,我们如何在不使用框架的情况下应用依赖注入(inject),而这两个 UIViewControllers 没有共同的父级。
例子:
VC1 -> VC2 -> VC3 -> VC4
VC5 -> VC6 -> VC7 -> VC8
让我们坐下来,他们都需要 VC4 和 VC8 UserService持有当前用户。
请注意,我们要避免单例。
有没有一种优雅的方法来处理这种 DI 情况?
经过一些研究,我发现有人提到了 Abstract Factory , Context interfaces , Builder , strategy pattern
但我找不到如何在 iOS 上应用它的例子
最佳答案
好的,我试试这个。
你说“没有单例”,所以我在下面排除了这一点,但也请看这个答案的底部。
Josh Homann 的评论已经是一个很好的解决方案的指针,但就我个人而言,我对协调器模式有疑问。
正如 Josh 正确说的那样, View Controller 不应该(很多)了解彼此 [1],但是如何例如传递/访问协调器或任何依赖项?有几种模式可以说明如何操作,但大多数模式都有一个基本上与您的要求背道而驰的问题:它们或多或少使协调器成为单例(本身或作为另一个单例的属性,如 AppDelegate )。协调器通常也被定义为单例(但并非总是如此,也不一定如此)。
我倾向于做的是依赖简单的初始化属性或 (最常见)懒惰的属性 和面向协议(protocol)的编程。让我们构建一个例子:UserService应是定义您的服务所需的所有功能的协议(protocol),MyUserService它的实现结构。让我们假设 UserService是一种设计结构,基本上用作某些用户相关数据的 getter/setter 系统:访问 token (例如保存在钥匙串(keychain)中)、一些首选项(头像图像的 URL)等。初始化时 MyUserService还准备数据(例如从远程加载)。这将用于多个独立的屏幕/ View Controller ,而不是单例。
现在每个有兴趣访问这些数据的 View Controller 都有一个简单的属性:
lazy var userService: UserService = MyUserService()
TestUserService)。实例化也可以是一个闭包,如果 init 需要参数,我可以在测试期间轻松切换它。显然,这些属性甚至不一定需要是 lazy取决于对象的实际作用。如果提前实例化对象没有坏处(记住单元测试,还有传出连接),只需跳过 lazy .UserService和/或 MyUserService以在创建它的多个实例时不会导致问题的方式 .但是,我发现这在 90% 的情况下并不是真正的问题,只要实例应该依赖的实际数据保存在其他地方,就一个事实而言,例如钥匙串(keychain),核心数据堆栈,用户默认值,或远程后端。prepareForSegue .这是有争议的,取决于您遵循协调员或其他模式的严格程度。就个人而言,我有时会在这里走捷径,只要它不会使事情变得臃肿和变得凌乱。一些弹出式设计通过这种方式更简单。UserService ,取决于它在您的应用程序中实际执行的操作可能是单例的理想选择。我个人的经验法则是:“如果它管理某种独特而独特的东西的状态,比如在给定时间只能处于一种状态的特定用户”,我可能会选择单例。关于ios - 快速依赖注入(inject),具有两个 UIViewController 的依赖关系图,没有共同的父级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53560257/
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是
我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#
我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里