2016-11-07 10 views
6

EDIT:この質問は、(クラスのプロパティだけでなく)通常の宣言されたプロパティにも当てはまります!`readonly`宣言されたプロパティ(クラスプロパティを含む)で`非原子的 'が意味を持ちますか?

オリジナルポスト:次のようになります

@interface MyClass 

+ (instancetype)sharedInstance; 

- (void)doSomething; 

@end 

@implementation MyClass 

+ (instancetype)sharedInstance { 
    static MyClass *shared = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     shared = [[MyClass alloc] init]; 
    }); 
    return shared; 
} 

@end 

スウィフト3.0で、このメソッドへのアクセス:

は、私は現在、getterメソッドとして実装されているパブリッククラスのメソッドsharedInstanceを考えてみましょうMyClass.shared().doSomething()

swifty私たちはクラスメソッドをクラスプロパティに変更する必要がありますXcodeの8.実際に、私は唯一のWWDC 2016のビデオでは、アップルのドキュでそれを見つけることができません)スウィフトコードで今すぐ

@interface MyClass 

@property (class, nonatomic, readonly) MyClass *sharedInstance; 

- (void)doSomething; 

@end 

// implementation stays the same 

nonatomic/atomicプロパティ修飾子(知らないMyClass.shared.doSomething()

そう厳密な用語)は、私がobjcで自分自身を実装するgetterメソッドにとっても意味がありますか?

+0

アトミックと非アトミックは、コンパイラがプロパティへの同時アクセスを処理するコードを生成する方法と関係します。アトミックプロパティを使用する場合、コンパイラは読み込み/書き込みの衝突を回避するために、ロックを使用してプロパティへの読み書きアクセスを囲みます。プロパティが変更された場合(クラス内からバッキングインスタンス変数を使用することを含む)、クラスのインスタンスに他のスレッドからアクセスできる場合は、おそらくアトミックにしておく必要があります。 –

+0

シングルトンのObjective-CクラスメソッドをObjective-Cプロパティに変換する方法がわかりません。質問の2番目の部分に投稿したコードは通常のインスタンスプロパティなので、シングルトンにアクセスすることはできません。 –

+1

@duncanc: '@property(class)'は、インスタンスプロパティではなくクラスプロパティにします。これはObjCアクセスには影響しませんが、Swift構文が変更されます。 – rickster

答えて

4

atomic/nonatomic修飾子は、複数の理由であなたのケースでは効果がありません。

主な理由は、アトミック性のキーワードが生成されたコード(合成されたアクセサメソッド)にのみ影響することです。あなたのインターフェイスに@propertyを宣言し、そのメソッド(またはメソッドのペア)をインプリメンテーションで実装すると、コンパイラはコードを生成しないので、atomicityキーワードは無視されます。

は、この状況を取得するには、いくつかの方法があります、そしてあなたはそれらのカップルをトリガしている:

  • まず、あなたがclass性質を持っています。コンパイラは、クラスプロパティのアクセサまたはストレージを合成できません。つまり、コード生成がないため、アトミック性は適用されません。

  • 第2に、宣言は、手作業で実装されたゲッターメソッドによってサポートされています。つまり、コード生成がないため、アトミック性は適用されません。

    (あなたは、インスタンスのプロパティが原因あなたの実装でプライベートreadwrite再宣言にパブリックインターフェイスにreadonlyとして宣言し、合成してきたことができます。その場合には、だけでなく、アトミックあなたはアトミックキーワードマッチを行う必要があり、適用されません「あなたのパブリックおよびプライベート宣言の間。あなたはまた、単にゲッターを合成し、あなたの実装でバッキングIVARを直接操作することができます。)

このプロパティにatomicまたはnonatomicのいずれかを指定すると、いずれかの方法何もしませんので、原子性のキーワードを残すだけで自由にあなたの宣言から完全に外してください。 (コンパイラはatomicと仮定しますが、その前提は何の効果もありません)。

+0

あなたは1つの可能性を見落としています。プロパティはクラス拡張で非公開に 'readwrite'で再宣言できます。また 'readwrite'プロパティが原子的であることは意味があります。つまり、' readonly'公開宣言も 'atomic'であると意味します。 – rmaddy

+0

@rmaddy:良い点。明確にするために編集。 – rickster

+0

修飾子 'atomic'は、読み取り専用のプロパティに影響します。合成された原子ゲッターは、戻り値をオートリリースプールに入れます。実装がivarに割り当てることができるので、setterのないreadonlyプロパティは有用なgetterを持つことができます。 – clemens

1

これは理にかなっています。プロパティの宣言は、クラス情報をユーザーに提供します。クラスのユーザーは、宣言であなたが何を伝えるか、合成された、または手動の実装から期待することができます。ユーザーは、合成されているかどうかを知ることさえできません。

ゲッター(またはアクセサー)を自分で実装する場合は、実装のアトミック性をプロパティの宣言に反映させる必要があります。非原子実装をお持ちの場合は、それを宣言されたプロパティに追加する必要があります。

+0

hmまた非常に有効な点です。それは本当です。パブリックAPIの観点からは、それらにアトミックなことを伝えるのは完全に意味があります – Buju

関連する問題