IOS 单例模式的学习

单例模式只能修改无法释放,直到程序结束。

我们下面一步一步来做一个单例模式程序

(1)单例一旦创建,是永远存在于内存中的,所以需要创建一个全局量

static MySingletonClass *sharedSingleTonObj=nil;

(2)既然是单例,一定有一个构造方法直接忽略跳过实例对象的生成过程。据此看来“类方法”最合适不过了

+(MySingletonClass *)sharedSingleton
{
    //多线程安全的关键字,相关概念可以参考多线程编程章节
     @synchronized(self)
     { 
           //创建
           if(sharedSingletonObj==nil)
           {
                 sharedSingletonObj= [[super allocWithZone:NULL] init];
            }
           //发出必要警告
            else
           {
                  NSLog(@"单例对象已经存在!");
           }
     }
     return sharedSingletonObj;
}

(3)如果对sharedSingletonObj执行了copy呢?我们需要重新写copy方法

-(id)copyWithZone:(NSZone *)zone
{
     return self;
}

(4)如果对sharedSingletonObj执行了retain呢?我们同样需要重写retain方法。

-(id)retain
{
    return self;
}

(5)继续对release和autorelease的方法重写

-(void)release
{
}

-(id)autorelease
{
     return self;
}

(6)重要的一点!我们需要实现NSObjec里面,关于引用计数API的重写以避免因为引用计数为0导致dealloc的触发

-(NSUInteger)retainCount
{
     //是一个无限大的int数,避免额系统自动触发单例dealloc方法
     //也可以明确告知调用者,这是一个单例模式
     return NSUIntegerMax;
}

(7)最后,你会发现就这样让人使用的话,如果不通过类方法创建对象转而调用alloc创建,则每次会分配新内存引用计数+1,显然alloc方法势必也不要重写

+(id)allocWithZone:(NSZone *)zone
{
      //直接套用sharedSingleton,retain 符合alloc惯例
      //使类方法返回的对象的引用计数+1,此处retain根据上面的重写内容,不做任何事情
      return [[MySingletonClass sharedSingleton] retain];
}

我们需要注意的时:往往只需要一个单例对象而已,但是如果仍相用alloc和init创建这个类的其他对象,那上述写法中,我们不需要重写2,3,4,5,6的代码

注:如果用gcd的话 ,只要在.m文件中实现这就可以 .h文件中声明一下这个 + (XEMessageData*) sharedInstance;

+ (XEMessageData*) sharedInstance
{
    static XEMessageData* sharedInstance;
    static dispatch_once_t predicate;
    dispatch_once(&predicate,^{
        sharedInstance = [[self alloc] init];
        sharedInstance.tempConversationMessageID2ConversationID = [[NSMutableDictionary alloc] init];
    });
   
    return sharedInstance;
}
原文地址:https://www.cnblogs.com/haibosoft/p/3656548.html