【问题标题】:singleton in objective c目标 c 中的单例
【发布时间】:2011-08-22 04:25:12
【问题描述】:
我在 Objective-c 书上看到了一个单例示例。但是,我不知道objective-c和其他语言之间的“单例”定义的含义是否存在差异。这个 [[SingletonClass alloc] init] 还能用来创建新对象吗?如果是,如何保证内存中只有一个对象?
#import "SingletonClass.h"
@implementation SingletonClass
static SingletonClass *sharedInstance = nil;
// Get the shared instance and create it if necessary.
+ (SingletonClass*)sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[super allocWithZone:NULL] init];
}
return sharedInstance;
}
// We can still have a regular init method, that will get called the first time the Singleton is used.
- (id)init
{
self = [super init];
if (self) {
// Work your initialising magic here as you normally would
}
return self;
}
【问题讨论】:
标签:
objective-c
ios
design-patterns
【解决方案1】:
如果您想要一个真正的单例,即只能实例化一次的对象,请查看 Apple 的文档:Creating a Singleton Instance。
基本上,想法是重写一些与分配和管理对象相关的方法:+allocWithZone(由+alloc调用)、-retain、-release、-copyWithZone等,这样就变得相当困难了创建一个以上的单例类实例。 (仍然可以通过直接调用运行时来创建第二个实例,但这应该足以理解这一点。)
几乎所有曾经以任何身份撰写过有关 Objective-C 的博主都对如何实现单例提供了意见。其中许多观点看起来都不错,而且大部分都非常相似。很明显,Dave DeLong 知道他在说什么,his piece on singletons 简短、甜美、直截了当。
【解决方案2】:
我不知道objective-c和其他语言之间的'singleton'定义是否有区别。
它遵循从 C 派生的语言的通用定义。
这个[[SingletonClass alloc] init]还能用来创建新对象吗?
是的
如果是,如何保证内存中只有一个对象?
避免强制执行该模式(例如,不要将其强制为单例)。只做一个普通的对象。然后,如果您真的只想要一个实例,请创建一个实例并将其保存在某个地方以供重复使用(您的应用委托是一个典型的地方,因为它通常在每次执行时创建一次)。
在实践中,我在野外看到的大多数 (>95%) ObjC 单例实现都用于错误的原因,并且会更好或与普通对象一样好。
到目前为止,答案中链接的每个解决方案都有(至少)微妙的问题、危险或不良副作用。
【解决方案3】:
没有对单例的语言支持,但您可以手动完成。查看单例示例here。不过,它看起来不像是线程安全的。我会在 +initialize 而不是 +sharedManager 中分配对象。
【解决方案4】:
您可以通过执行以下操作在 Objective-C 中创建单例:
+(MyAPI *)shared {
static dispatch_once_t queue;
static MyAPI *singleton = nil;
dispatch_once(&queue, ^{
singleton = [[MyAPI alloc] init];
});
return singleton;
}
这也将确保它是线程安全的。如果不使用dispatch_once,您将面临多个线程同时尝试访问它的风险,此时一个线程正在分配它,而另一个线程正在尝试使用它。
【解决方案5】:
Singleton 类用于保存数据以供在应用中的任何位置使用。
//SingletonObject
#define saveDataSingletonObject ((SaveDataSingleton*)[SaveDataSingleton sharedManager])
@interface SaveDataSingleton : NSObject
@property (nonatomic,strong) NSMutableArray *DataArr;
+ (id)sharedManager;
-(void)clearAllSaveData;
@end
@implementation SaveDataSingleton
@synthesize DataArr;
+ (id)sharedManager {
static SaveDataSingleton *sharedManager;
if(!sharedManager) {
@synchronized(sharedManager) {
sharedManager = [SaveDataSingleton new];
}
}
return sharedManager;
}
-(void)clearAllSaveData{
DataArr=nil;
}
- (id)init {
if (self = [super init]) {
DataArr = [[NSMutableArray alloc]init];
}
return self;
}
// using setter getter save and retrieve data
+(void)setDataArr:(NSMutableArray *)Dataarr
{
self.DataArr = [[NSMutableArray alloc]initWithArray:Dataarr];
}
+(NSMutableArray *)DataArr
{
return self.DataArr;
}
@end
保存和检索数据 // 使用单例对象
// save data using setter function.
[saveDataSingletonObject setDataArr:Array];
//fetch data using getter function.
NSArray *arr=[saveDataSingletonObject DataArr];