スキップしてメイン コンテンツに移動

Objective-Cの手習い:Singletonパターン

今回は『Java言語で学ぶデザインパターン入門』からSingltonパターン。

至って簡単なプログラムだが、Objective-Cでの注意点は3つ。

  1. クラス変数がないこと
  2. メソッドの可視性を設定できないこと
  3. 決まった形式でのコンストラクタのようなものがないこと

Javaなどではクラス変数にSingletonインスタンスを納めておくのが通常だが、Objective-Cではスタティック変数を用意して格納しておくことにする。@implementaion部の最初に以下のように宣言する。

static Singleton* s_singleton = nil;

また、2と3の問題からJavaのようにコンストラクタをプライベートにして生成を制御するということができない。

で、NSObjectから継承された新たにインスタンスを作成しそうな基本メソッドをまずオーバーライドしていく。具体的にはallocWithZone/copyWithZoneなどがそれにあたる。また解放に関する部分も勝手に解放されてはまずいので手を入れておく(retain/retainCount/release/autoreleaseなど)。

具体的にはSingletonクラスの基本メソッドのオーバーライド部分は以下のようになる。

+(id)allocWithZone:(NSZone*)zone
{
    @synchronized(self) {
        if(!s_singleton) {
            s_singleton = [super allocWithZone:zone];
        }
    }
    //アップルのガイドでは最初はインスタンスを返し以降はnilを返すことに
    //なっているが、それだとうまくいかないので以下のように常にインスタンス
    //を返すように変更
    return s_singleton; 
}

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

-(id)retain
{
    return self;
}
-(unsigned)retainCount;
{
    //解放できないオブジェクトであることを示す
    return UINT_MAX; 
}
-(void)release
{
    return;
}

-(id)autorelease
{
    return self;
}

で肝心のインスタンスを提供するメソッドは以下のようになる。

+(id)getInstance
{
    @synchronized(self) {
        if(!s_singleton) {
            s_singleton = [[self alloc] init];
            printf("インスタンスを生成しました。\n");
        }
    }
    return s_singleton;
}

@synchronizedを入れているのはマルチスレッドへの考慮だ。

実はこの辺りの解説はアップルが提供するデザインガイド「Cocoa Fundamentals Guide」に「シングルトンインスタンスの作成」という解説があり、コードのサンプルも掲載され詳しく説明されている。今回はほとんどその受け売り。

SingletonSample.zip

コメント

このブログの人気の投稿

Scrivener 日本語チュートリアル

(2022-01-11) 以前からコメントをいただいていましたが、反応できていなく申し訳ありません。 問い合わせが多いので、以下のブログに転載してチュートリアルもダウンロードできるようにしました。 転載先 先日から[試していたScrivenerだが、すっかり気に入り勢い余ってチュートリアルの日本語訳版を作ってしまった。 作者にコンタクトしたところ、「どうぞ、公開しておくれ!」と快く承諾をもらえたので公開しておく。 チュートリアル自体はわたしが慣れないBritish Englishで書かれているため、微妙なニュアンスは違っている箇所があるかもしれあない。また、チュートリアル自体に関係ない言い回しなどは、端折ったり日本語に合うようにゆがめたりしている。誤りがあれば指摘ください。 Scrivener-Tutorial-Japanese.dmg(リンクを切りました。転載先をごらんください。) ちなみに作者のKeithは豪気にもライセンス進呈を申し出てくれたが、入れ違いで購入してしまっていたわたし…… (2010-09-20) 「 design non design 」で紹介いただきました。

iOS5に上げたらやっておくべきこと

忘備録。 今さらながら、iOS5にバージョンアップしたときにやっておくべきことを書き出しておこう。わたし自身はiPhone4持ちですが、3Sでも結構動いている模様なので、参考にどうぞ。 通知関連 iOS5になって通知機能が充実してMobile機器としてさらに使いやすくなったが、反面バッテリーを食う原因ともなっているようだ。不用なアプリの通知については個別にオフに設定したほうがよいだろう。 また、「緊急地震速報」はバージョンアップした場合はデフォルトではオフになっています。但し書きに「設定をオンにした場合バッテリーも持ち時間が短くなる場合があります」と書かれている。今沖縄住まいなのでとりあえずオフのままにしておこう。 位置情報サービス 先日報告されたiPhone 4Sのバッテリー異常消費の原因とも見なされている機能だが、ネットではこのシステムサービスの設定が原因とささやかれていたものだ。まずはアプリの一覧が表示されているが、位置情報が不用と思われるアプリについてはセキュリティの観点からもオフにしておきましょう。 さて、一番下にある「システムサービス」だが、コンパスの調整以外はすべてオフでよいと思われる。ちなみに「位置情報に基づくiAd」は無料アプリに表示される広告に位置情報が加味されるサービス。「携帯電話通信網検索」はキャリアは固定だろうからあまり意味がない。「時間帯の設定」は海外旅行に頻繁に行く人しか意味がない。「渋滞状況」は日本ではサービスが始まっていない。 「システムサービス」の「診断/使用状況」はAppleに自動送信されている情報に位置情報を含めるための設定。Appleには悪けれど、そうでなくてもAppleにたくさんお布施をしている我が身なればさらに通信費まで負担して貢献する気持ちにはなれない。よって、「診断/使用情報」を送る設定自体をオフにしちゃいましょう。変更は「設定」> 「情報」> 「診断/使用状況」 で「送信しない」を選択すればよい。 Spotlight検索 インデックス構築にバッテリーが消費されるらしいので不用なものはチェックを外そう。「設定」>「一般」>「Spotlight検索」で。わたし自身ほとんど利用しないので全部外してしまった。 キーボード設定 不用なキーボードをオフっておくのはこれまで通りだが、今回日本語に入力でこれまでの「かな入力」の他に...

スターシップ・トゥルーパーズ

『スターシップ・トゥルーパーズ』を見る。 1997年の作品で15年近く昔の映画だからか? いや、制作にかかわってるフィル・ティペットが関わった『ジェラシック・パーク』は1993年のはずだ。原作がヘボなのか? いや、原作はハイラインの『宇宙の戦士』のはずだ、あれは昔、俺も読んだぞ…… なんだろう? このやるせなさは。 CGもそんなに古さを感じさせないし、ストーリーもまぁ設定がベタなところはあるが構想はでかい。うーん 問題なのは脚本と演出と演技か。見てる印象は、アホで安直なアメリカンな80年代以前の古くさいSF映画だ。それがもしかしたら狙った演出なのかと思う節もあるが、狙いも分からん。質のいい大阪漫才を観たあとで、くそ下手なボケにラフトラック無理矢理入れたシットコムを見せられた気分だ。 たとえば、こんな具合…… 宇宙戦艦に巨大アステロイドが急接近。未来の宇宙戦艦がそんな急接近されるまで気付かず、パイロットが目視で発見というところは許そう。今にも衝突しそうで警報がバンバン鳴っている中、回避操作に取り掛かったヒロインのセリフが「緊急回避、3、2、1、ゴー!」…… 数えてないで、早くハンドル切ってよ。 揚げ句の艦橋上部がへし折れて宇宙の大海原で通信機能が失われおそらく何名か亡くなっているのに、館長のセリフが「助かったわ、パイロットのおかげよ、ナイスジョブ」…… いや、あの3秒がなければ無傷だったと思うよ、戦艦も。 このヒロインは常にこんな調子。 戦艦が爆発しかけて脱出ボートも次々の火に巻き込まれていくなか、脱出ボートに乗り込んで礼儀正しくヘルメットして「用意はいい、いくわよ」、「ガァーーーーーーーーーーーーーーー(キャノピーを閉める音)」「発射!」…… 早く逃げろよ、イライラする。 まぁ、こういう楽しみ方をするならお勧めです。 敵が「虫」なのだが、地上から攻撃出来る対宇宙戦艦の屁をこく虫がいるとか、相手が虫なのに死んでもいない主人公を死んだことにして諜報戦でもやってるつもりの歩兵隊とか…… スターシップ・トゥルーパーズ [DVD] posted with ama...