iOS Singleton 单例模式

本文介绍了一种使用Objective-C实现单例模式的方法,包括利用宏定义简化实现过程,并提供了详细的代码示例。通过这种方式,可以有效地确保在整个应用中只有一个类实例,并提供一个全局访问点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.  为 Singleton Object 实现一个静态实例,并初始化,然后设置成nil;

2. 实现一个实例构造方法 (通常命名为 sharedInstance 或者 sharedManager) 检查上面声明的静态实例是否为nil,如果是,则新建并返回一个本类实例;

3. 重写allocWithZone: 方法,用来保证当其他人直接使用 alloc 和init 试图获得一个新实例的时候,不会产生一个新的实例。

4. 适当地实现  allocWithZone,  copyWithZone,  release 和 autorelease。

MyGizmoClass.h:

+(MyGizmoClass *)sharedGizmoManager;


MyGizmodClass.m:

static MyGizmoClass *sharedGizmoManager = nil;

+ (MyGizmoClass*)sharedManager

  {

  @synchronized(self) {

  if (sharedGizmoManager == nil) {

  [[self alloc] init]; // assignment not done here

  }

  }

  return sharedGizmoManager;

}



 + (id)allocWithZone:(NSZone *)zone

  {

  @synchronized(self) {

  if (sharedGizmoManager == nil) {

  sharedGizmoManager = [super allocWithZone:zone];

  return sharedGizmoManager; // assignment and return on first allocation

  }

  }

  return nil; //on subsequent allocation attempts return nil

}

 - (id)copyWithZone:(NSZone *)zone

{

  return self;

}

 - (id)retain

{

  return self;

}

- (unsigned)retainCount

{

  return UINT_MAX; //denotes an object that cannot be released

}

- (void)release

{

  //do nothing

}

- (id)autorelease

{

  return self;

}

程序员都是偷懒的,现在流行使用一个宏定义来搞定这许多的事,而且考虑的更加周全。

  单例包含以下接口

  + (MyClass*) sharedInstance;

  + (void) purgeSharedInstance;

  调用sharedInstance会创建并返回单例

  调用purgeSharedInstance会销毁单例

  手动调用alloc也可以保证是单例,你可以这样调用

  [[MyClass alloc] initWithParam:firstParam secondParam:secondParam];

  只是要保证在sharedInstance之前调用,因为只有一次创建机会。

  下面是使用宏的写法“


#ifndef SYNTHESIZE_SINGLETON_FOR_CLASS

#import <objc/runtime.h>


#pragma mark -
#pragma mark Singleton

 #define SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(__CLASSNAME__)    \
    \
+ (__CLASSNAME__*) sharedInstance;    \
+ (void) purgeSharedInstance;


#define SYNTHESIZE_SINGLETON_FOR_CLASS(__CLASSNAME__)    \
    \
static volatile __CLASSNAME__* _##__CLASSNAME__##_sharedInstance = nil;    \
    \
+ (__CLASSNAME__*) sharedInstanceNoSynch    \
{    \
    return (__CLASSNAME__*) _##__CLASSNAME__##_sharedInstance;    \
}    \
    \
+ (__CLASSNAME__*) sharedInstanceSynch    \
{    \
    @synchronized(self)    \
    {    \
        if(nil == _##__CLASSNAME__##_sharedInstance)    \
        {    \
            _##__CLASSNAME__##_sharedInstance = [[self alloc] init];    \
        }    \
        else    \
        {    \
            NSAssert2(1==0, @"SynthesizeSingleton: %@ ERROR: +(%@ *)sharedInstance method did not get swizzled.", self, self);    \
        }    \
    }    \
    return (__CLASSNAME__*) _##__CLASSNAME__##_sharedInstance;    \
}    \
    \
+ (__CLASSNAME__*) sharedInstance    \
{    \
    return [self sharedInstanceSynch]; \
}    \
    \
+ (id)allocWithZone:(NSZone*) zone    \
{    \
    @synchronized(self)    \
    {    \
        if (nil == _##__CLASSNAME__##_sharedInstance)    \
        {    \
            _##__CLASSNAME__##_sharedInstance = [super allocWithZone:zone];    \
            if(nil != _##__CLASSNAME__##_sharedInstance)    \
            {    \
                Method newSharedInstanceMethod = class_getClassMethod(self, @selector(sharedInstanceNoSynch));    \
                method_setImplementation(class_getClassMethod(self, @selector(sharedInstance)), method_getImplementation(newSharedInstanceMethod));    \
                method_setImplementation(class_getInstanceMethod(self, @selector(retainCount)), class_getMethodImplementation(self, @selector(retainCountDoNothing)));    \
                method_setImplementation(class_getInstanceMethod(self, @selector(release)), class_getMethodImplementation(self, @selector(releaseDoNothing)));    \
                method_setImplementation(class_getInstanceMethod(self, @selector(autorelease)), class_getMethodImplementation(self, @selector(autoreleaseDoNothing)));    \
            }    \
        }    \
    }    \
    return _##__CLASSNAME__##_sharedInstance;    \
}    \
    \
+ (void)purgeSharedInstance    \
{    \
    @synchronized(self)    \
    {    \
        if(nil != _##__CLASSNAME__##_sharedInstance)    \
        {    \
            Method newSharedInstanceMethod = class_getClassMethod(self, @selector(sharedInstanceSynch));    \
            method_setImplementation(class_getClassMethod(self, @selector(sharedInstance)), method_getImplementation(newSharedInstanceMethod));    \
            method_setImplementation(class_getInstanceMethod(self, @selector(retainCount)), class_getMethodImplementation(self, @selector(retainCountDoSomething)));    \
            method_setImplementation(class_getInstanceMethod(self, @selector(release)), class_getMethodImplementation(self, @selector(releaseDoSomething)));    \
            method_setImplementation(class_getInstanceMethod(self, @selector(autorelease)), class_getMethodImplementation(self, @selector(autoreleaseDoSomething)));    \
            [_##__CLASSNAME__##_sharedInstance release];    \
            _##__CLASSNAME__##_sharedInstance = nil;    \
        }    \
    }    \
}    \
    \
- (id)copyWithZone:(NSZone *)zone    \
{    \
    return self;    \
}    \
    \
- (id)retain    \
{    \
    return self;    \
}    \
    \
- (NSUInteger)retainCount    \
{    \
    NSAssert1(1==0, @"SynthesizeSingleton: %@ ERROR: -(NSUInteger)retainCount method did not get swizzled.", self);    \
    return NSUIntegerMax;    \
}    \
    \
- (NSUInteger)retainCountDoNothing    \
{    \
    return NSUIntegerMax;    \
}    \
- (NSUInteger)retainCountDoSomething    \
{    \
    return [super retainCount];    \
}    \
    \
- (void)release    \
{    \
    NSAssert1(1==0, @"SynthesizeSingleton: %@ ERROR: -(void)release method did not get swizzled.", self);    \
}    \
    \
- (void)releaseDoNothing{}    \
    \
- (void)releaseDoSomething    \
{    \
    @synchronized(self)    \
    {    \
        [super release];    \
    }    \
}    \
    \
- (id)autorelease    \
{    \
    NSAssert1(1==0, @"SynthesizeSingleton: %@ ERROR: -(id)autorelease method did not get swizzled.", self);    \
    return self;    \
}    \
    \
- (id)autoreleaseDoNothing    \
{    \
    return self;    \
}    \
    \
- (id)autoreleaseDoSomething    \
{    \
    return [super autorelease];    \
}

#endif 

用法:

MyClass.h:
 * ========================================
 *	#import "SynthesizeSingleton.h"
 *
 *	@interface MyClass: SomeSuperclass
 *	{
 *		...
 *	}
 *	SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(MyClass);
 *
 *	@end
 * ========================================
 *
 *
 *	MyClass.m:
 * ========================================
 *	#import "MyClass.h"
 *
 *	@implementation MyClass
 *
 *	SYNTHESIZE_SINGLETON_FOR_CLASS(MyClass);
 *
 *	...
 *
 *	@end
 * ========================================


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值