Objective Cでシングルトンクラスを作成するにはどうすればよいですか?
AppDevにわかりました。Web上でこれを行うためのさまざまなテクニックを見つけることができるでしょう。ただし、iOSアプリ開発の場合、次の方法が最も便利な方法だと思います。
シングルトンオブジェクトを取得するためのメソッドを記述します。 (推奨:dispatch_once
スレッドとGCDを使用してください)。
メソッドをマクロでラップし、$Project$-Prefix.pch
ファイルに追加します。
クラスにシングルトンオブジェクトが必要な場合は、1行マクロを呼び出します。
例:
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
ここでは、目的の+(id)SampleSingletonClassの代わりに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;
}
From:http://www.galloway.me.uk/tutorials/singleton-classes/
Objective-Cのシングルトン
IOS用に開発するときに最もよく使用されるデザインパターンの1つは、シングルトンパターンです。手動でデータをやり取りすることなく、コードの異なる部分間でデータを共有するための非常に強力な方法です。
背景
シングルトンクラスは、非常に有用なデザインパターンを示すため、理解する重要な概念です。このアイデアは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メソッドを使用します。これはスレッドセーフであり、OSによって完全に処理されるため、まったく心配する必要はありません。
これを試して
シングルトンクラス.hファイル
#import <Foundation/Foundation.h>
@interface GlobleDirector : NSObject
+(GlobleDirector*)shareManager;
@end
シングルトンクラス.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;
}
#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;
}
訪問者はシングルトンとは何かを知っていると思われますが、知らない人を助けるために、共有データを使用したこの簡単な小さな例を提案します。
オブジェクトは、共有データクラスインスタンスまたはクラスインスタンスに使用されます。
@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/
これは、シングルトンクラスを作成する正しい方法です。
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;
}
他のクラスのシングルトンクラスのプロパティまたはメソッドにアクセスする方法
anotherClass.m
Bool isTokenValid = [mySingletonClass sharedInstance].useToken;
以下のコードを試してください。
@implementation AppShared
static AppShared *singletonInstance;
+ (AppShared*)Instance{
if (singletonInstance == nil) {
singletonInstance = [[super alloc] init];
}
return singletonInstance;
}