0

我正在为现有的单例类创建一个包装类。由于我将多次访问单例,我想将它作为 ivar 存储在我的包装类中......

@interface WrapperClass () 

@property (nonatomic, strong) SingletonClass singletonObj;

@end

...这样我就不必经常写了[[SingletonClass sharedInstance] methodName]。相反,我可以写[singletonObj methodName]. 我只是觉得它更干净。

我是 iOS 开发的新手,所以我想知道这种方法是否存在根本性的问题。

另外,对于 ARC,我应该使用强引用存储单例吗?

4

3 回答 3

2

除非你做一些疯狂的事情,否则额外的保留/释放应该不会引起任何问题。

因此,将其存储在 ivar 中没有真正的问题......

这样做的更好理由不是节省您的打字,而是提高类的可测试性/可重用性。通过使其成为 ivar,它允许您注入不同的类来改变行为。

我会考虑制作一个访问器,默认情况下会给我单例,但如果我这样选择,仍然允许我注入不同的类

- (SingletonClass *)singletonObj;
{
  return _singletonObj = _singletonObj ?: [SingletonClass sharedInstance];
}

更新:

还值得思考“为什么要使用这个单例与使用 ivar 不同?”。如果您在整个课堂上都像使用 ivar 一样使用它,那么为什么要以完全不同的方式访问它呢?

例如,当我经常使用 a 时managedObjectContext,我的整个应用程序中只有一个。很多人将应用程序委托用作单例并以这种方式访问​​它,但我更喜欢将它作为 ivar 传递。从概念上讲,这managedObjectContext只是我像任何其他 ivar 一样使用的另一个对象,所以为什么我必须在心理上改变我访问它的方式?

这是不好的

[(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];

好的

self.managedObjectContext;

现在这给了我两个好处。

  1. 如果我的班级到处都是调用,[(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];那么很难将其从这个项目中剥离出来并将其放在另一个项目中,而无需进行冒险的搜索和替换。如果我在“访问器”的一个地方访问单例,那么我只有一个地方可以更改代码。

  2. 在我的生产应用程序中,我可能希望我的数据是持久的,所以我会给对象访问一个managedObjectContext带有持久存储的对象,而在我的测试中,我不希望在测试之间保持状态,所以我会给对象一个非持久的而是存储。

于 2012-12-09T23:48:04.273 回答
1

这说得通。只需初始化您的单例并将其存储在 ivar 中。也就是说,您的代码实际上是在定义一个属性,这与 ivar 不同。

例如,您可以定义您的单例 i var,如下所示

@implementation WrapperClass {
    SingletonClass * _singleton;
}

然后在默认构造函数中初始化单例

- (id)init {
    self = [super init];
    if (self) {
        //...
        _singleton = [SingletonClass sharedInstance];
        //...
    }
    return self;
}
于 2012-12-09T23:31:55.973 回答
0

您可以只定义一个宏,如下所示:

#define _SINGLETON(method) { [[SingletonClass sharedManager] method]; }

然后你可以像这样在你的代码中使用它:

_SINGLETON(methodName);

你可以在 SingletonClass.h 中定义这个宏,然后你就可以在任何地方使用它,在那里你的头文件被导入。这样您就无需考虑 iVar。

于 2012-12-10T10:04:27.957 回答