【发布时间】:2011-03-21 17:07:33
【问题描述】:
如何在 Objective C 中创建单例类?
【问题讨论】:
标签: iphone objective-c singleton
如何在 Objective C 中创建单例类?
【问题讨论】:
标签: iphone objective-c singleton
好的 appDev,您可能会在网络上找到很多不同的技术来执行此操作。但是,对于 iOS 应用开发,我认为最方便的方法是执行以下操作:
编写获取单例对象的方法。 (建议:为此使用dispatch_once 线程和 GCD)。
将您的方法包装在一个宏中并将其添加到您的$Project$-Prefix.pch 文件中。
当你需要一个类的单例对象时调用单行宏。
例子:
CommonMacros.h:
#define SINGLETON_FOR_CLASS(classname)
+ (id) shared##classname {
static dispatch_once_t pred = 0;
static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init];
});
return _sharedObject;
}
YourProject-Prefix.pch:
...
#import "CommonMacros.h"
...
YourSingletonClass.m:
...
SINGLETON_FOR_CLASS(YourSingletonClass)
...
查看此链接以获取原始来源 - http://getsetgames.com/2009/08/30/the-objective-c-singleton/
@implementation MySingleton
static MySingleton *_sharedMySingleton = nil;
+(MySingleton *)sharedMySingleton {
@synchronized([MySingleton class]) {
if (!_sharedMySingleton)
_sharedMySingleton = [[self alloc] init];
return _sharedMySingleton;
}
return nil;
}
【讨论】:
我确实认为这是我们真正实现单例行为的方式:
@interface SampleSingletonClass : NSObject
+ sharedSampleSingletonClass;
@end
@implementation SampleSingletonClass
static SampleSingletonClass *singletonObject = nil;
+ (id) sharedSampleSingletonClass
{
if (! singletonObject) {
singletonObject = [[SampleSingletonClass alloc] init];
}
return singletonObject;
}
- (id)init
{
if (! singletonObject) {
singletonObject = [super init];
// Uncomment the following line to see how many times is the init method of the class is called
// NSLog(@"%s", __PRETTY_FUNCTION__);
}
return singletonObject;
}
@end
这里即使调用了 init 方法而不是预期的 + (id) SampleSingletonClass;方法实际对象在应用程序的整个生命周期中只形成一次。
【讨论】:
class Class { static let shared = Class() private init() {} }
这是我个人最喜欢的方式:
+ (instancetype)sharedObject {
static id instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
【讨论】:
你可以在 Objective-C 中实现一个单例类。
+ (id)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (id)init {
if (self = [super init]) {
someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
}
return self;
}
【讨论】:
发件人: http://www.galloway.me.uk/tutorials/singleton-classes/
Objective-C 中的单例
在为 iOS 开发时,我最常用的设计模式之一是单例模式。这是一种非常强大的方式,可以在代码的不同部分之间共享数据,而无需手动传递数据。
背景
单例类是一个需要理解的重要概念,因为它们展示了一种非常有用的设计模式。这个想法在整个 iPhone SDK 中都有使用,例如,UIApplication 有一个名为 sharedApplication 的方法,当从任何地方调用该方法时,将返回与当前运行的应用程序相关的 UIApplication 实例。
如何实施
Singletone.h
#import <foundation/Foundation.h>
@interface Singleton : NSObject {
}
@property (nonatomic, retain) NSString *someProperty;
+ (id)sharedManager;
@end
Singleton.m
#import "Singleton.h"
@implementation Singleton
@synthesize someProperty;
#pragma mark Singleton Methods
+ (id)sharedManager {
static Singleton *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (id)init {
if (self = [super init]) {
someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
}
return self;
}
@end
它的作用是定义一个名为 sharedMyManager 的静态变量(但仅限于该翻译单元的全局变量),然后在 sharedManager 中初始化一次且仅一次。我们确保它只创建一次的方法是使用 Grand Central Dispatch (GCD) 中的 dispatch_once 方法。这是线程安全的,完全由操作系统为您处理,因此您完全不必担心。
【讨论】:
试试这个
Singalton 类 .h 文件
#import <Foundation/Foundation.h>
@interface GlobleDirector : NSObject
+(GlobleDirector*)shareManager;
@end
Singalton 类 .m 文件
#import "GlobleDirector.h"
@implementation GlobleDirector
+(GlobleDirector*)shareManager{
static GlobleDirector *sharedInstance=nil;
static dispatch_once_t oncePredecate;
dispatch_once(&oncePredecate,^{
sharedInstance=[[GlobleDirector alloc] init];
});
return sharedInstance;
}
@end
【讨论】:
static DBHandler* sDBHandler = nil;
- (id)init
{
self = [super init];
if (self) {
[self checkAndCreateDatabase];
}
return self;
}
+(id)sharedDBHandler
{
@synchronized (self) {
if (sDBHandler == nil) {
sDBHandler = [self new];
}
}
return sDBHandler;
}
【讨论】:
我知道访问者应该知道什么是单例,但为了帮助那些他们不知道的人,我提出了一个共享数据的简单小示例。
该对象用于共享数据类实例或类实例。
@interface SharedData : NSObject {
id data;
}
- (void)setData:(id)data_;
- (id)data;
@end
@implementation SharedData
//>> singleton
static SharedData *sharedData=nil;
+ (SharedData*)sharedData {
@synchronized (self) {
if (sharedData==nil) sharedData=[[self alloc]init];
}
return sharedData;
}
//<<
- (void)setData:(id)data_ {
data=data_;
}
- (id)data {
return data;
}
@end
... 第一次调用 (+ sharedData) 实例化对象,基于它作为实例引用返回的静态(区域设置共享)变量的引用。下一次调用只返回对静态变量的引用。
可以使用嵌入式访问器随时设置/获取数据。
共享对象相对简化,但可以通过引用共享“手动”处理。
@synchronized 只需要多线程。对于简单的类实例,不需要共享它。
这里有一个扩展的解释:http://www.galloway.me.uk/tutorials/singleton-classes/
【讨论】:
#import <Foundation/Foundation.h>
@interface singt : NSObject
+ (id)sharedManager;
@end
#import "singt.h"
@implementation singt
+ (id)sharedManager
{
static singt *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
【讨论】:
这是创建单例类的正确方法
mySingletonClass.h
@interface mySingletonClass : NSObject
+ (mySingletonClass*)sharedInstance;
@property (nonatomic, assign)BOOL useToken;
mySingletonClass.m
@implementation mySingletonClass
static mySingletonClass *_sharedInstance = nil;
+ (mySingletonClass*)sharedInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[self alloc] init];
});
return _sharedInstance;
}
如何访问另一个类中的单例类属性或方法
另一个类.m
Bool isTokenValid = [mySingletonClass sharedInstance].useToken;
【讨论】:
请尝试以下代码。
@implementation AppShared
static AppShared *singletonInstance;
+ (AppShared*)Instance{
if (singletonInstance == nil) {
singletonInstance = [[super alloc] init];
}
return singletonInstance;
}
【讨论】:
+ (id)sharedInstance {
static dispatch_once_t pred = 0;
__strong static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init];
});
return _sharedObject;
}
- (id)init {
self = [super init];
if (self) {
}
return self;
}
并在 .h 中添加
+ (id)sharedInstance;
PD:你的类应该继承自 NSObject 。
记住要使用sharedinstance时总是调用它,而不是调用init。
【讨论】:
在swift 1.2 或更高版本中,如果类名是例如:singletonVC
class singletonVC {
static let sharedMySingleton = singletonVC()
private init(){
}
}
实施:
singletonVC.sharedMySingleton.yourFunctionName
【讨论】: