当我使用 static 实现单例时,有什么可能出错的地方吗?

发布于 2025-01-01 14:46:19 字数 325 浏览 2 评论 0原文

我正在实现一个单例类(如果这是错误的,我们就不要参与讨论)。我有一个方法来获取此类的实例,该实例是延迟初始化的:

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

  return dm;
}

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

I'm implementing a singleton class (and lets not get into the discussion if that is wrong or not). I have a method to get the instance of this class, which is lazily initialized:

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

  return dm;
}

Is there anything I should look out for when doing this using static (inside of the method) as opposed to creating a global variable? Is there anything that can go wrong, all tutorials on the Internet use a global variable.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

╰沐子 2025-01-08 14:46:19

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

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

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

    return shared;
}

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

My preferred singleton implementation looks like:

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

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

    return shared;
}

Using dispatch_once makes sure this is also thread safe. Your code would allocate twice when accessed by multiple threads at the same time.

﹉夏雨初晴づ 2025-01-08 14:46:19

回答原来的问题(其他人已经解决了初始化的最佳方法):

使用静态(方法内部)而不是创建全局变量来执行此操作时,有什么我应该注意的吗?

不。

区别在于可见性而不是生命周期

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

如果您仅在一个函数中使用全局变量,那么您所做的就是好的 - 它将可见性限制在需要的地方,同时保持执行生命周期。任何初始化程序都运行一次,就像文件级全局变量一样。

To answer the original question (others have address the best way to do initialization):

Is there anything I should look out for when doing this using static (inside of the method) as opposed to creating a global variable?

No.

The difference is over visibility and not lifetime.

  • A global's (with or without static) lifetime is that of the application execution.
  • A global without static is visible throughout the whole application. From anywhere else it can be referenced by naming it in an extern statement.
  • A global with static is visible just in the containing compilation unit (which is typically a single file, but #import/#include can change that).
  • A variable declared within a function/method as static is a global which is only visible within that function/method.

If you're using a global in just one function what you've done is good - it limits the visibility to just where it is needed while keeping execution-lifetime. Any initializer is run once, just as for file-level globals.

待"谢繁草 2025-01-08 14:46:19

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

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

我会采用静态全局方法。

编辑:
看看 http://www.johnwordsworth。 com/2010/04/iphone-code-snippet-the-singleton-pattern/

What you create is a static local variable. Static local variables retain their value through successive method invocations. They can only be accessed from within the method which they are defined in. When apps start static local variables are set to 0 once.

So what you do in my opinion is with every call of sharedDataManager you declare a new static local variable and set it to nil. I don't think that's necessary or even good. And also every time if (!dm) checks dm it is nil because you set dm to nil the line before.

I'd go with the static global approach.

Edit:
Have a look at http://www.johnwordsworth.com/2010/04/iphone-code-snippet-the-singleton-pattern/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文