Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.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
Objective c 当我使用static实现一个单例时,有什么可能出错吗?_Objective C_Singleton - Fatal编程技术网

Objective c 当我使用static实现一个单例时,有什么可能出错吗?

Objective c 当我使用static实现一个单例时,有什么可能出错吗?,objective-c,singleton,Objective C,Singleton,我正在实现一个单例类(如果这是错误的或不是错误的,我们就不要再讨论了)。我有一个方法来获取这个类的实例,它是惰性初始化的: + (FFDataManager *)sharedDataManager { static FFDataManager *dm = nil; if (!dm) { dm = [[FFDataManager alloc] init]; } return dm; } 与创建全局变量相比,使用static(方法内部)执行此操作时,是否需要注意什么?是否

我正在实现一个单例类(如果这是错误的或不是错误的,我们就不要再讨论了)。我有一个方法来获取这个类的实例,它是惰性初始化的:

+ (FFDataManager *)sharedDataManager {
  static FFDataManager *dm = nil;
  if (!dm) {
    dm = [[FFDataManager alloc] init];
  }

  return dm;
}

与创建全局变量相比,使用
static
(方法内部)执行此操作时,是否需要注意什么?是否存在任何可能出错的地方,Internet上的所有教程都使用全局变量。

我首选的单例实现如下所示:

+ (MyClass *) sharedInstance {
    static dispatch_once_t predicate = 0;
    __strong static MyClass *shared = nil;

    dispatch_once(&predicate, ^{
        shared = [[self alloc] init];
    });

    return shared;
}

使用
dispatch\u一次
确保这也是线程安全的。当多个线程同时访问时,您的代码将分配两次。

您创建的是一个静态局部变量。静态局部变量通过连续的方法调用保持其值。只能从中定义它们的方法中访问它们。应用启动时,静态局部变量设置为0一次

因此,在我看来,每次调用
sharedDataManager
都会声明一个新的静态局部变量,并将其设置为
nil
。我认为这不是必要的,甚至不是好的。而且每次
if(!dm)
检查
dm
时,它都是
nil
,因为您之前将dm设置为nil行

我会采用静态全局方法

编辑:
查看

以回答原始问题(其他人有解决初始化问题的最佳方法):

在使用静态(方法内部)而不是创建全局变量时,我应该注意什么

没有

区别在于过度可见性,而不是寿命

  • 全局的(有无静态)生存期是应用程序执行的生存期
  • 在整个应用程序中都可以看到一个不带
    的全局静态
    。从任何其他地方都可以通过在
    extern
    语句中命名来引用它
  • 带有
    static
    的全局文件仅在包含的编译单元中可见(通常是单个文件,但
    #import
    /
    #include
    可以更改该文件)
  • 函数/方法中声明为
    static
    的变量是全局变量,它仅在该函数/方法中可见

如果您只在一个函数中使用全局函数,那么您所做的很好-它将可见性限制在需要的位置,同时保持执行生命周期。任何初始值设定项都会运行一次,就像文件级全局值一样。

返回
id
是否会更好,那么如果执行子类,就不必执行强制转换?您还需要将
MyClass
更改为
id
。这也是一种可能性。我将原始答案中的id改为显式类名,以匹配问题。“…每次调用sharedDataManager时,您都会声明一个新的静态局部变量…”但在第一段中,您只是说它们“通过连续的方法调用保留其值。”我是不是遗漏了什么?@WTP'--不,你没有遗漏任何东西。对不起,drct,但这个答案是错误的。我从来没有说过要使它成为静态局部变量。顺便说一句,我刚刚描述了实现苹果推荐的单例的方法<代码>SingletonClass.m#导入“SingletonClass.h”@implementation SingletonClass静态SingletonClass*sharedInstance=nil;//获取共享实例并在必要时创建它(SingletonClass*)sharedInstance{if(sharedInstance==nil){sharedInstance=[[super-allocWithZone:NULL]init];}返回sharedInstance;}…
谢谢大家的支持。但也许你做得太快了。