0

好的,我知道这个问题可能看起来无关紧要或太基本,但是 - 因为我一直想知道我在做什么以及我为什么要这样做,如果它符合我的设计 - 请阐明一下。

所以,这就是我需要的:

  • 假设我们有一堂课
  • 我们想在几乎任何地方使用它的方法
  • 我决定使用类方法和伪全局实例,而不是传递一个对象

所以,假设我们有一个名为“MyDocumentManager”的类。


这是我通常做的:

+ (MyDocumentManager*)documentManager
{
     MyDocumentManager* newDocumentManager = [[MyDocumentManager alloc] init];

     if (newDocumentManager)
     {
          // initialize that new document manager
     }
     return newDocumentManager;
}

然后像这样使用它:

[[MyDocumentManager documentManager] someMethod];

但是,我经常看到人们提出类似的建议:

+ (MyDocumentManager*)sharedManager
{
    static dispatch_once_t pred;
    static MyDocumentManager *sharedManager;
    dispatch_once(&pred, ^{
        sharedManager = [[MyDocumentManager alloc] init];
    });
    return sharedManager;
}

所以,这是我的问题:

  • 是一样的吗?
  • 如果不是,有什么区别?
  • 它的方法的优点/缺点是什么?(在内存/速度/等方面)
  • 我应该使用哪一个,为什么?
  • 它们都适合我需要它们吗?
4

2 回答 2

2

是一样的吗?

不。

如果不是,有什么区别?

您所拥有的并没有实现单例,因为它在每个函数调用时都分配了一个新的类实例。它被称为工厂方法。单例的定义是某个类方法总是返回该类的同一个实例。

我应该使用哪一个,为什么?

您通常应该避免使用单例,因为它通常被认为是不好的做法,尽管在某些情况下使用它们很方便。例如,如果你有一个使用封装数据的类,但你只需要准类级别的方法,那么最好实现一个带有适当放置的实例变量的单例,而不是实现类方法和大量的全局/静态变量(这是因为在Objective-C,类不能有成员变量,只有对象)。

它们都适合我需要它们吗?

你决定那个。

于 2013-03-03T07:45:32.767 回答
1

您粘贴在“我通常做什么”中的代码已损坏。它不返回单例。每次调用它时它都会返回一个全新的对象(如果这不是 ARC,那么它也会泄漏它)。

您按照人们的建议粘贴的代码是正确的代码。它不仅每次都返回一个共享对象而不会泄漏,而且它也是线程安全的(就对象的初始化而言;它没有说明对象的使用是否是线程安全的)。

于 2013-03-03T07:46:00.540 回答