【问题标题】:Can i achieve the real singleton in objective-c like java c#我可以像java c#那样在objective-c中实现真正的单例吗
【发布时间】:2012-10-19 12:59:47
【问题描述】:

init 方法是在 NSObject 类中声明的,因此客户端代码可以创建我的单例类的新实例,有什么方法可以实现真正的单例,使客户端无法创建新实例。

【问题讨论】:

标签: objective-c ios cocoa-touch


【解决方案1】:

这样做:

 static SingletonClass  *singleton;

+ (SingletonClass *)sharedInstance 
 {
     @synchronized(self) { //For thread safety
         if (singleton == nil) {
           [[self alloc] init];
         }
         return singleton;
      }
 }


  -(id)init
   {
      if (singleton) { //This way init will always return the same instance
         return singleton;
       }
       self = [super init];
       if (self) {
           singleton = self; 
       }
       return singleton;

   }

【讨论】:

  • 如果客户端执行[[SingletonClass alloc] init],您将泄漏一个实例。您需要在返回singleton 之前丢弃传递给initself 实例,或者覆盖allocWithZone: 以返回共享实例,这样它就是传递给init 的实例。
  • 你确定这会随着电弧泄漏吗?我的印象是自动释放池会放弃它。
  • 如果 self 曾经进入自动释放池,那么 ARC 需要做一些认真的工作。
  • 我刚刚做了一个快速的示例项目,它实际上已经发布了。所以你错了,ARC确实会处理它,这里没有泄漏。
  • 这很有趣。你会把你的测试代码扔到pastebin还是别的地方?
【解决方案2】:

这是在目标 c 中做单例的正确方法

+ (id)sharedManager
{
    static dispatch_once_t onceQueue;
    static SingletonObjectClass *singleton = nil;

    dispatch_once(&onceQueue, ^{
        singleton = [[self alloc] init];
    });

    return singleton;
}

- (id)init {
    self = [super init];
    if (self) {
       //.....
    }
   return self;
}

【讨论】:

  • 就其本身而言,这不会将创建限制为仅一个实例。一个客户仍然可以alloc另一个客户。
【解决方案3】:

init 方法用于初始化实例变量。本身不会创建对象。需要重写 alloc、copy 方法才能实现真正的单吨。

希望这应该澄清。

+ (id)alloc {
    NSLog(@"%@: use +sharedInstance instead of +alloc", [[self class] name]);
  return nil; 
}
+ (id)new {
 return [self alloc];
}

+ (SingletonClass *)sharedInstance {
static SingletonClass *myInstance = nil; 
 if (!myInstance)
 {
    myInstance = [[super alloc] init];
 }
 return myInstance; 
}

【讨论】:

  • 我仍然无法从客户端代码中隐藏 alloc 方法,因为它是在 NSObject 中声明的。
【解决方案4】:

您可以每次返回一个类的静态对象,使其成为单例。

@implementation Singleton
@synthesize testVar;

+ (Singleton*) sharedObject {
    static Singleton * myInstance = nil;
    if (myInstance == nil) {
        myInstance = [[[self class] alloc] init];
        testVar = 5;
        // Set default values if needed
    return myInstance;
}

访问对象及其成员:

[[Singleton sharedObject] testVar]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-02
    • 1970-01-01
    • 2018-04-05
    • 2014-06-27
    • 1970-01-01
    • 1970-01-01
    • 2017-02-13
    • 2018-02-04
    相关资源
    最近更新 更多