2016-05-31 13 views
1

自体にインスタンス変数に割り当て:実装ファイルで私は<code>School</code>クラスに<code>mTeacher</code>変数インスタンスを持つ

@interface School : NSObject { 
    Teacher *mTeacher; 
} 
@end 

を、私は1つまたはがある場合は、既存の教師のインスタンスのいずれかを返すことになっている方法- (Teacher *)getTeacherを持っています1を作成し、それを返す:

- (Teacher *)getTeacher { 
    if (mTeacher != nil) { 
     return mTeacher; 
    } 
    return [[Teacher alloc] init]; 
} 

Teacherインスタンス&割り当てを取得するには、このメソッドを呼び出して、他の複数のインスタンスメソッドがあるかもしれませんインスタンス変数:だから

- (void)methodOne { 
    mTeacher = [self getTeacher]; 
    ... 
} 

- (void)methodTwo { 
    mTeacher = [self getTeacher]; 
    ... 
} 

、(- (Teacher *)getTeacher方法は、単に、この場合mTeacherを返すため)mTeacherに既にTeacherのインスタンスを割り当て方法のいずれか、他の方法[self getTeacher]を呼び出す下mTeacher = mTeacherで終わるかどう。私の質問は、それは客観的なCでうまくいくのですか?私のgetTeacherメソッドの潜在的な問題?

+0

シングルトンデザインパターンを実装しています。ここでは、助けてくださいトピックに関する別の関連する投稿があります:http://stackoverflow.com/questions/145154/what-should-my-objective-c-singleton-look-like –

+1

私はそれに技術的に何か間違って表示されませんが、 'init'メソッドで変数を一度初期化し、それを複数回設定するのではなく、必要なところで使うのはなぜですか? (スタイルに関しては、Objective-Cで明示的変数ではなく 'teacher'をプロパティにすることが多くなります。その後、' init'についての提案と一緒に、あなたのコードから「getter」が消えます) –

+0

'mTeacher'が決して' nil'でない場合、 'School'の' init'メソッドで初期化してみませんか?また、これをチェックする必要があります[Objective-cのプロパティ](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html) – Sudo

答えて

0

客観的には良いです!! mTeachernilでない場合のみ、それはgetTeacher呼ばれますので、他のような、

- (void)methodOne { 

    if(!mTeacher){ 
    mTeacher = [self getTeacher]; 
    } 
    ... 
    } 

- あなたは私が考えていますが、場合に確認することができ、この問題となってはなりません。

目的では、propertyを使用できます。それはそれのgetterメソッドとsetterメソッドを設定します。または、initメソッドで一度初期化するには、このオブジェクトが必要です。このようにする必要はありません。

1

変数を遅延的にインスタンス化したいようです。

Objective-Cの通常のパターンは、読み取り専用(非原子的)プロパティを宣言し、初期化にバッキングインスタンス変数を使用することです。

@interface School : NSObject 

@property (readonly, strong, nonatomic) Teacher *mTeacher; 

@end 

@implementation School 
@synthesize mTeacher = _mTeacher; 

- (Teacher *)mTeacher { 
    if (!_mTeacher) { 
     _mTeacher = [[Teacher alloc] init]; 
    } 
    return _mTeacher; 
} 

@end 

編集:直接インスタンス変数プロパティへのアクセスを使用しない場合:しかし、あなたが書くためにあなたが持っているインスタンス変数ではなく、明示的にゲッターを使用したい場合は

@interface School : NSObject 
{ 
    Teacher *mTeacher; 
} 

@end 

@implementation School 

- (Teacher *)mTeacher { 
    if (!mTeacher) { 
    mTeacher = [[Teacher alloc] init]; 
    } 
    return mTeacher; 
} 

@end 

[self mTeacher]; 
+0

私は非常に興味があります怠惰な初期化のために '@ property'を使わずにバージョンを知るために、私にもそれを表示できますか? –

+0

すべてのアクセサを上書きすると、暗黙のうちにivarが作成されないため、その例のコンパイルは行われません。 –

+0

@vadianの例を追加しました。 –

0

このアプローチには何も問題はありません。なぜ、学校のinitでTeacherオブジェクトを作成できないのですか?また、マルチスレッド環境で作業している場合、Teacherオブジェクトを複数回作成していないことを確認してください。

+0

コードはスレッドセーフではありません。しかし、アクセサをスレッドセーフにすることは、多くの場合意味がありません。だから、誰も原子アクセサーを使用していないのです。しかし、スレッドセーフであることを望むなら、今日はGCDを使うべきです。 –

+0

私は、インスタンス(initメソッド)を作成する場所ではなく、アクセサーではない場所を守る必要があるということです。 – Feroz

+1

@Feroz:遅延初期化は非常に有用で、多くの場合必須です。 – gnasher729

1

アプローチは正しいですが、二つの発言があります。

A.あなたは、プロパティnil'd意味「ノー先生」scheool、ということはありません - 何のために。

B.明らかに、Objective-Cの他の言語から来て起動します。

  • "メンバー" のためm接頭辞を使用しないでください。 (彼らはメンバーではなく、イヤーズです。)

  • インタフェースにivarsを宣言しないでください。

  • getterに接頭辞getを使用しないでください。ヴァディアンで述べたように

あなたは、プロパティを使用することができます。

@interface School : NSObject 
@property (readonly, strong, nonatomic) Teacher *teacher; // without m 
- (Teacher*)teacher; // *Alternatively* without @property 
@end 

@implementation School 
// usually the ivar is created implicitly with the name _teacher. 
// However, you have a readonly property and overwrite all accessors 
// (in the case of a read only property there is only a getter) of the property, 
// no ivar will be created automatically. You have to do that explicitly. 
{ 
    Teacher *_teacher; 
} 

- (Teacher *)teacher { // no m 
    if (!_teacher) 
    { 
    _teacher = [[Teacher alloc] init]; 
    } 
    return _teacher; 
} 
@end 

はさらに、このコードはスレッドセーフではありません。

関連する問題