2015-11-17 26 views
1

我有什么工作:目标C - 辛格尔顿静态方法重载并不多子

我在我的项目中多个单身人士和他们分享一些范围,领域和功能。所以我决定构建它们并创建一个名为BaseSingleton的父类。作为一个单身人士,它有+(instancetype) sharedInstance,所以它的所有子类。现在我有一个BaseSingleton类和三个子类:

  • PublicApi
  • UserService
  • OrderStorage

在BaseSingleton +(instancetype) sharedInstance有一个常见的实现:

+(instancetype) sharedInstance { 
    static BaseSingleton* _sharedInstance = nil; 
    static dispatch_once_t once_token; 
    dispatch_once(&once_token, ^{ 
     _sharedInstance = [[self alloc] init]; // no override for init method 
    }); 
    return _sharedInstance; 
} 

我需要:

当我们调用sharedInstance时,我需要我的Singleton子类正常工作。这意味着,PublicApi返回PublicApiUserService回报UserServiceOrderStorage回报OrderStorage例如,没有必要实施sharedInstance一个实例。

的问题是什么:

所以我认为,利用instancetype+(instancetype) sharedInstance会做的工作,因为使用instancetype使类方法的返回相关的返回类型(在NSHipster article读取)。因此,如果在PublicApi或UserService上调用,则sharedInstance将返回相关类型,分别为PublicApi或UserService(同样,在两者中都没有实现sharedInstance)。

这只适用于一个子类(PublicApi)。但是当添加其他两个子类时,在其中一些子类上调用sharedInstance不会完全导致正确的返回类型。因此,例如,[PublicApi sharedInstance]将返回PublicApi的实例,但[UserService sharedInstance]也会返回PublicApi的实例,对于OrderStorage也是如此。

我认为这个问题在于静态_sharedInstance[BaseSingleton sharedInstance]的实现。 [PublicApi sharedInstance]在应用程序运行时期间首先被调用,所以dispatch_once方法实例化_sharedInstance并给它一个PublicApi类型。 dispatch_once中的代码块永远不会再次执行,这就是为什么该静态变量永远不会更改其类型,并返回 [UserService sharedInstance][OrderStorage sharedInstance]

任何优雅的方式来做我在问什么? (当然,除了每个子类实现sharedInstance,这都会破坏从BaseSingleton继承的全部目的)。

回答

4

单身人士的共同基类本身就是一个矛盾。

显而易见的是,使用sharedSingleton实现时,只有一个 dispatch_once_t令牌。因此dispatch_once_t中的代码只会在您的应用程序中执行一次。 _sharedInstance也只有一个静态变量,所以它不可能返回两个不同的sharedInstance值。

不要这样做。

+1

我决定创建一个只有目的的基类 - 避免代码重用。它真的让我困扰,我的所有单例都有相同的sharedInstance实现,除了返回的_sharedInstance类型。所以我试图找出重构这种方式 – AzaFromKaza

+1

@AzaFromKaza例如逻辑上我想'+(instancetype)sharedInstance'将在运行时返回给我适当的Type,但是如果你能看到只有'BaseSingleton'会得到一个实例,所以它不介意任何其他类,所以'BaseSingleton'只是想由于dispatch_once初始化一次,然后当你第二次请求它时,已经有一个'BaseSingleton'并且不需要初始化新的一。 –

1

如前所述,这个架构有问题,说这是很有可能的。在sharedInstance中,如果'self'(class)== say [Public class] else,你需要级联一组测试。