2013-10-26 9 views
6

私は現在、客観C.ルビー|| =同等

にはるかに簡単に後半のようルビーを学習し、それは怠惰なゲッターを書いなるだろうと|| =機能と恋に基本的に午前してきましたイムは、||と何かが欠けていない限り

- (NSArray *)myArray { 
    if (!_myArray) { 
    _myArray = [NSArray array]; 
    } 
    return _myArray 
} 

は=私が使ってRubyで前のコードを記述することができるだろう:

- (NSArray *)myArray { 
    return _myArray ||= [NSArray array]; 
} 

ザッツ明らかに非常にクリーン私は、次のようなゲッターを書きます。 Objective-C言語/ランタイムにこれを行うための何かがありますか?

また、以下はgetterの1行の3進数です。上に掲載された試行錯誤したメソッド(最初のスニペット)と同じ効果があるかどうかはわかりません。やって何も悪いことをtheresの場合、誰かが私を伝えることができます:

- (NSArray *)myArray { 
    return _myArray = _myArray ? _myArray : [NSArray array]; 
} 
+0

Objective Cは分かりませんが、クラスのコンストラクタや初期化メソッドで '_myArray = [NSArray array];'再び、Objective C:p – David

+1

を知らない人による潜在的な提案スレッド安全性を気にするなら、上記のすべてが間違っていることに注意してください。 –

+1

マルチスレッド化では、スレッドAがセッターを呼び出し、非nilテストに失敗し、スレッドBがプリエンプトする可能性があります。スレッドBもセッターを呼び出し、非nilテストに失敗します。両方のスレッドは、新しいNSArrayを作成し、それを '_myArray'に格納することを決めました。喜びが続く。 –

答えて

10

最後のスニペットは、あなたが投稿最初のものと同じ効果があります。 Objective-Cの中||=ようには、オペレータはありませんが、あなたはオペレータあれば三元の2番目のパラメータを省略し、

return _myArray = _myArray ? _myArray : [NSArray array]; 
とまったく同じである

return _myArray = _myArray ?: [NSArray array]; 

を行うことができ改良として

これは現代版のgccclangでサポートされている言語拡張です。

ボーナス:あなたはいくつかのより多くのキーストロークを保存したい場合、あなたはまた、いくつかの利点を持つことができます真ん中のオペランドを飛ばし、サイドノートとして

- (NSArray *)myArray { 
    return _myArray = _myArray ?: @[]; 
} 

を行うことができます。

この場合、例えば

id x = [self someMethod] ? [self someMethod] : [self anotherMethod]; 

someMethodtrueと評価された場合、それは一度だけ呼び出されます

id x = [self someMethod] ?: [self anotherMethod]; 

を行うのに対し、二回呼び出されます。

+0

私はこれが大好きで、私の三者の検証を提供し、それを改善します。いい物。非常に悲しいtheresない|| =しかし。 –

+0

確かに、Objective-CはRubyよりはるかに古い言語だと考えてください。さらに、元のCよりも薄いレイヤーなので、言語に「無関係な」演算子を導入しないという設計選択に同意します。 –

3

hack on Clangにしたい場合を除き、同等のリテラルはありません。 ||論理演算子は、短絡している間にそのオペランドに評価されません。 Cでの割り当ては、一種の表現のように機能し、割り当てられた値に評価されるため

#define NON_NIL(o, p) ((o) ? (o) : (p)) 

- (NSMutableArray *)myArray 
{ 
    return _myArray = NON_NIL(_myArray, [NSMutableArray array]); 
} 

を:三条件を使用したマクロは、あなたが閉じて取得します。

OR_ASSIGN()マクロを実際に作成することもできますが、私はそれを完全に混乱した読者のための練習として残します。おそらく、同じように錯乱

関数のようになります。

id lazySet(id *obj; id(^valBlock)(void)) 
{ 
    if(!(*obj)){ 
     *obj = valBlock(); 
    } 
    return *obj; 
} 

- (NSMutableArray *)myArray 
{ 
    return lazySet(&_myArray, ^{return [NSMutableArray array]}); 
} 

それはちょうどばかげなってきました。

+0

魅力的だが怖いと種類の醜い参照してください。とにかく私はちょうど新しい言葉を学んだ。私は確かに数日後にそれを乱用するつもりです。英語レッスンありがとう。 –

+0

ああ、 "欠落中"の '?:'演算子を使って最初のマクロを改善することができます –

+0

私の喜び、@Gabriele! (それを指摘してくれてありがとう、私は多分中間のオペランドを放置しないように少しだけ不合理な好みがあります) –