12

Objective-C でシングルトンを実装する方法に関する多くのスレッドやブログ記事を読んできましたが、そのうちのいくつかは少し非推奨 (2010 年以前) である可能性があり、この問題に関してはさまざまな意見があるようです。 .. Apple には、シングルトンの実装に関するドキュメントがありますか? 私はそれを見つけることができませんでした。もしそうなら、誰かが私にどこを教えてもらえますか?

パブリック変数とプライベート変数の両方を持つクラスにシングルトンが必要です。現在、これは私がそのようなクラスのために持っている実装です:

@interface MySingleton ()
   @property (strong, nonatomic) NSString *state;
@end

@implementation MySingleton

@synthesize state = _state;
@synthesize count = _count;

static MySingleton *sharedObject = nil;

+ (MySingleton *)sharedInstance
{
   static dispatch_once_t _singletonPredicate;

   dispatch_once(&_singletonPredicate, ^{
      sharedObject = [[super allocWithZone:nil] init];
   });

   return sharedObject;
}

+ (id)allocWithZone:(NSZone *)zone 
{
   return [self sharedInstance];
}

これは推奨される方法でしょうか?また、パブリックとプライベートのインスタンス変数をどのように初期化すればよいですか?

シングルトンについて明確にしたいもう 1 つの問題は、これによりメモリ リークが発生するかどうかです。シングルトンの使用は実際にiOSで推奨されていますか?

ありがとう

4

5 に答える 5

12

上記は、sharedInstance メソッド内に静的オブジェクトを含めることに関する @miho のコメントとともに正しいです。しかし、オーバーライドする理由はありません+allocWithZone:。ObjC のシングルトンは通常、強制ではなく「共有」されます。「シングルトン」の他のインスタンスを自由に作成できます。他のインスタンスを作成することが違法である場合は、 で呼び出し元をだますのではなく、をinit実行する必要があります。シングルトンがミュータブルである場合 (そしてほとんどがミュータブルである場合)、この方法を絶対にオーバーライドしないでください。NSAssert+allocWithZone:+allocWithZone:

シングルトンについて明確にしたいもう 1 つの問題は、これによりメモリ リークが発生するかどうかです。

いいえ。このオブジェクトは解放されませんが、常にアクセス可能です。それは漏れではありません。

シングルトンの使用は実際にiOSで推奨されていますか?

はい、これは非常に一般的なパターンであり、Cocoa フレームワーク全体で使用されています。とはいえ、最近開発者の間でやや人気が出始めているさまざまなパターンがあります。依存性注入は、実際にはあまり見かけませんが、ある程度の関心を集めています。シングルトンへの依存を減らすことでテスト容易性を向上させることができます。私は最近、コード内でそれらのいくつかを排除する方法を実験しており、ある程度の成功を収めています。しかし、彼らは Cocoa で長く誇り高い歴史を持っており、私はそれらが問題だとは考えていません。

編集: コードに実際のバグが 1 つあります。[[self alloc] init]ではなく、を呼び出す必要があります[[super alloc] init]。を呼び出す理由はありません。+allocWithZone:ただ使用して+allocください。(...WithZone:メソッドが便利だった時代はとうの昔に過ぎました。)

于 2013-03-17T17:43:06.383 に答える
3

Xcode で、「Search Documentation」の下に「Creating a Singleton Instance 」と入力します。多くの結果があります (ただし、ページの下部にある上記のリンクにはサンプル コードがあります)。

于 2013-03-17T17:28:42.097 に答える
1

はい、これが推奨される方法です。使用方法の小さな違いが 1 つだけあります。getter メソッド以外の場所から変数にアクセスすることはできないため、メソッドsharedObject内で静的変数として定義します。+ (MySingleton *)sharedInstance

いいえ、メモリ リークは発生しません。アプリが終了すると、アプリで使用されているすべての予約済みメモリがとにかく解放され、静的共有インスタンスを解放する必要がある他の状況はありません。releaseARC 以前の領域では、メソッドをオーバーライドして、オブジェクトが誤って解放されるのを防ぐことさえ一般的でした。

于 2013-03-17T17:36:07.623 に答える
0

私はまだCocoaWithLoveのシングルトン ヘッダーを使用しています。少し古いかもしれませんが、魅力的に機能します。基本的には、Apple のドキュメントを参照してここで説明したのと同じことを行います。少なくとも Apple のドキュメント (このページの下部) はまだ有効であると思います。Appleが提案した公式の解決策であるため、無期限に有効であると想定している人がいます.

于 2013-03-17T22:12:23.980 に答える
0

シングルトンに gcd を使用する場合の警告:

dispatch_once(&_singletonPredicate, ^{
      sharedObject = [[super allocWithZone:nil] init];
   });

何らかの理由で init メソッドがシングルトン オブジェクトを直接的または間接的にアドレス指定すると、デッドロックが発生します。このため、シングルトンを記述するより適切な方法は、

+ (void) initialize

方法

于 2013-03-17T19:01:50.103 に答える