我应该将单身作为ivar存放吗?

时间:2012-12-09 23:24:43

标签: ios iphone objective-c singleton automatic-ref-counting

我正在为现有的单例类创建一个包装类。因为我将多次访问单身人士,所以我想将它作为ivar存储在我的包装类中......

@interface WrapperClass () 

@property (nonatomic, strong) SingletonClass singletonObj;

@end

...所以我不必经常写[[SingletonClass sharedInstance] methodName]。相反,我可以写[singletonObj methodName]。它对我来说感觉更干净。

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

另外,使用ARC,我应该存储具有强引用的单例吗?

3 个答案:

答案 0 :(得分:2)

除非你做某事疯狂,否则额外保留/释放的可能性应该没有问题。

因此将它存放在ivar中没有真正的问题...

执行此操作的更好理由不是保存您的输入,而是提高类的可测试性/可重用性。通过使它成为一个ivar,它允许你注入一个不同的类来改变行为。

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

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

更新

同样值得思考的是“你为什么要使用这种与使用ivar不同的单身?”。如果你在整个班级使用它,就像它是一个ivar那么你为什么要以完全不同的方式访问它?

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

这很糟糕

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

self.managedObjectContext;

现在这给了我两个好处。

  1. 如果我的课程中充满了对[(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];的调用,那么很难将其从这个项目中删除并将其放在另一个项目中而不会进行风险搜索和替换。如果我在一个地方访问单一的“访问者”,那么我只有一个地方可以更改代码。

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

答案 1 :(得分:1)

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

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

@implementation WrapperClass {
    SingletonClass * _singleton;
}

然后在默认构造函数

中初始化单例
- (id)init {
    self = [super init];
    if (self) {
        //...
        _singleton = [SingletonClass sharedInstance];
        //...
    }
    return self;
}

答案 2 :(得分:0)

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

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

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

_SINGLETON(methodName);

你可以在SingletonClass.h中定义这个宏,然后你可以在任何地方使用它,你的头被导入。 这样你就不需要考虑iVars了。