Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 是否跳过singleton对象的初始化?_Ios_Objective C_Singleton_Init - Fatal编程技术网

Ios 是否跳过singleton对象的初始化?

Ios 是否跳过singleton对象的初始化?,ios,objective-c,singleton,init,Ios,Objective C,Singleton,Init,我的应用程序中实现了一个单例,但在视图控制器之间切换时遇到了问题 我的应用程序在一个视图控制器MainMenu中启动,然后在选择菜单时切换到游戏视图控制器。我在游戏VC中有一个单例类,它是游戏的对象管理器(称为World)。它根据主菜单中的菜单选择加载内容。我可以加载并退出主菜单。Singleton很好用。当我再次从主菜单选择(从主菜单VC转到游戏VC)时,我的应用程序崩溃,原因是NSAssert阻止单身世界分配第二次,这是故意的 我如何切换回游戏VC,而不尝试重新初始化我的单身 基本上,我想跳

我的应用程序中实现了一个单例,但在视图控制器之间切换时遇到了问题

我的应用程序在一个视图控制器MainMenu中启动,然后在选择菜单时切换到游戏视图控制器。我在游戏VC中有一个单例类,它是游戏的对象管理器(称为World)。它根据主菜单中的菜单选择加载内容。我可以加载并退出主菜单。Singleton很好用。当我再次从主菜单选择(从主菜单VC转到游戏VC)时,我的应用程序崩溃,原因是NSAssert阻止单身世界分配第二次,这是故意的

我如何切换回游戏VC,而不尝试重新初始化我的单身

基本上,我想跳过我的游戏VC的init方法中的
[[world alloc]init]
行。我不知道该怎么做。。。它需要能够在第一次(当世界不存在时)或任何后续时间(当世界已经作为一个单体存在时)处理。我尝试了
if(!world)
,但没有成功

这也引出了一个问题。。。我在正确的地方实现了我的单例吗?我应该把它放在主菜单里吗?我只是想避免在两个VCs之间切换时尝试重新初始化/重新分配单例


如果这有帮助,我将使用
[self.view removeFromSuperview]退出游戏VC我应该用另一种方式吗?

如果我正确理解了这个问题,您想知道如何创建Singleton类吗?最近,一种常见的方式是使用大中央调度,如下所示:

+ (MyViewController*)shared
{
    static dispatch_once_t onceToken;
    static MyViewController* instance;

    dispatch_once(&onceToken, ^
    {
        instance = [[[self class] alloc] init];
    });
    return instance;
}
然后,您可以通过以下方式访问该实例:

[MyViewController shared];
在grandcentraldispatch之前,该技术是在类上放置一个静态实例,并在调用共享访问器时检查它是否为nil。访问器需要用@synchronized(self)包装,以确保线程安全。GCD方式的表现稍好一些

话虽如此,我还是建议你有选择地使用单身。研究为什么它们被视为反模式,并研究依赖注入作为替代方案

依赖注入与单例对比

单例的问题是,它们可能导致紧密耦合。假设您正在构建一个航空公司预订系统。您的预订管理员可能会使用:

id<FlightsClient>
为了使用单例测试类,您现在必须同时测试单例,这可能会变得很棘手,尤其是当您的应用程序变得更加复杂时。想象一下测试类A,依赖于类B,依赖于类C,依赖于。。。。没什么好玩的

另一种方法是使用依赖项注入,这仅仅意味着使用初始值设定项或属性设置项将预订客户端传递给预订控制器。您可以手动执行此操作,也可以使用库执行此操作。如果手动执行此操作,则仍然可以声明singleton,尽管可以说您不需要这样做,因为顶级程序集类可以保留该实例

通过对单例使用这种替代方法,类将具有松散耦合,并且易于测试和维护。(使用依赖项注入,您将有一个同样花哨的名字;))


我基于Spring编写了一个依赖注入库:

如果我正确理解了这个问题,您想知道如何创建Singleton类吗?最近,一种常见的方式是使用大中央调度,如下所示:

+ (MyViewController*)shared
{
    static dispatch_once_t onceToken;
    static MyViewController* instance;

    dispatch_once(&onceToken, ^
    {
        instance = [[[self class] alloc] init];
    });
    return instance;
}
然后,您可以通过以下方式访问该实例:

[MyViewController shared];
在grandcentraldispatch之前,该技术是在类上放置一个静态实例,并在调用共享访问器时检查它是否为nil。访问器需要用@synchronized(self)包装,以确保线程安全。GCD方式的表现稍好一些

话虽如此,我还是建议你有选择地使用单身。研究为什么它们被视为反模式,并研究依赖注入作为替代方案

依赖注入与单例对比

单例的问题是,它们可能导致紧密耦合。假设您正在构建一个航空公司预订系统。您的预订管理员可能会使用:

id<FlightsClient>
为了使用单例测试类,您现在必须同时测试单例,这可能会变得很棘手,尤其是当您的应用程序变得更加复杂时。想象一下测试类A,依赖于类B,依赖于类C,依赖于。。。。没什么好玩的

另一种方法是使用依赖项注入,这仅仅意味着使用初始值设定项或属性设置项将预订客户端传递给预订控制器。您可以手动执行此操作,也可以使用库执行此操作。如果手动执行此操作,则仍然可以声明singleton,尽管可以说您不需要这样做,因为顶级程序集类可以保留该实例

通过对单例使用这种替代方法,类将具有松散耦合,并且易于测试和维护。(使用依赖项注入,您将有一个同样花哨的名字;))


我基于Spring编写了一个依赖注入库:

我能够解决这个问题,正如我所想,我确实将单例初始化向上移动到了主菜单视图控制器中。在我的设计中,VC的
init
只在应用程序启动时调用一次,而我的游戏VC中的自定义
init
方法每次切换到它时都会被调用


我不确定这是否是我应该使用的最佳设计,但它现在起作用。

我能够解决这个问题,正如我所想,我确实将单例初始化移到了主菜单视图控制器中。在我的设计中,VC的
init
只在应用程序启动时调用一次,而我的游戏VC中的自定义
init
方法每次切换到它时都会被调用

不确定这是否是最佳设计