2012-02-12 14 views
0

C構造体またはpre-iOS5基本型のクラスプロパティを初期化する方法がわかりません。これは私がクラスを扱っていた場合私がやっていることですが、作成時に定義されていないので、構造体が初めてアクセスされたかどうか確認することはできません。C構造体の遅延初期化

@interface GraphView : UIView 
@property (nonatomic) CGPoint origin; 
@end 


@implementation GraphView 
@synthesize origin = _origin; 

- (CGPoint)origin 
{ 
    if (WHAT?) { 
     _origin = CGPointMake(self.bounds.origin.x + self.bounds.size.width/2, 
           self.bounds.origin.y + self.bounds.size.height/2); 
    } 
    return _origin; 
} 

@end 

私はレイジー初期化の主な利点はメモリ割り当てのためであることを認識していますが、クラスであるすべてのプロパティに対してこれを行っている場合、同じスタイルを使用してすべてのプロパティで開始値を設定するのが最も明白です。

他のインスタンス変数やプロパティを使用して、self.originにアクセスしたかどうかを追跡できますが、そのように見えます...滑らかではありません。私はそれを設定する前にself.originにアクセスしないように気をつけることができました。これは、構造体が作成時に定義されていないという事実によって軽く随伴されるようです。

"正しい"方法はありますか?

答えて

5

objcクラスのすべてのメンバーは、作成時に(構造体さえも)ゼロに初期化されます。私はあなたにメモリ割り当てについてのポイントを与えることはありません。スペースは構造体のために予約されています(あなたはそれへのポインタを格納していません)。それに値を割り当ててもいなくても、同じスペースが必要です。

+0

右。ありがとうございました。スタック上のstructは設定されるまで定義されていないので、ここでは定義されません。しかし、そうです。 – bsdfm

+0

@rasmus、これを説明できますか? http://stackoverflow.com/questions/13372551/c-struct-not-initialized-to-zero-in-objective-c – Philip007

0

一般に、ポインタにはnilのようなインバンド無効状態が必要です。あなたのケースでは、それらが決して有効でないことがわかっている場合は、!CGPointEqualToPoint(_origin, CGPointZero)または!CGPointEqualToPoint(_origin, CGPointMake(-1,-1))をテストすることができます。 (_originCGPointZeroにデフォルト設定されますか、init場合(0、0)に有効です。で(-1、-1)に設定する必要があります)すべての可能な帯域内の値が有効であれば

、あなたあなたが言及したように、帯域外の旗で立ち往生しています。

きれいな方法はBOOLを保存することになる、あなたのCGPointが初期化されているかどうかの情報を保持します:CGPoint

0

遅延評価は、(少なくとも)2つの異なる方法を行うことができます。

場合
@interface GraphView : UIView { 
    BOOL _originInitialized; 
} 
@property (nonatomic) CGPoint origin; 
@end 

@implementation GraphView 
@synthesize origin = _origin; 

// extend the init methods 
-(id) init { 
    ... 
    _originInitialized = NO; 
    ... 
} 

- (CGPoint) origin { 
    if (_originInitialized) { 
     _origin = CGPointMake(self.bounds.origin.x + self.bounds.size.width/2, 
           self.bounds.origin.y + self.bounds.size.height/2); 
     _originInitialized = YES; 
    } 
    return _origin; 
} 
@end 

あなたがテストするために、初期値を汚いアプローチ を行うと、使用できるメモリのBOOL無駄にしたくないあなたの_originに対する:

@interface GraphView : UIView 
@property (nonatomic) CGPoint origin; 
@end 

@implementation GraphView 
@synthesize origin = _origin; 

// extend the init methods 
-(id) init { 
    ... 
    _origin = CGPointMake(-23.0, -42.0); 
    ... 
} 

- (CGPoint) origin { 
    if (_origin.x == -23.0 && _origin.y == -42.0) { 
     _origin = CGPointMake(self.bounds.origin.x + self.bounds.size.width/2, 
           self.bounds.origin.y + self.bounds.size.height/2); 
    } 
    return _origin; 
} 
@end 

しかし、私は」 dは2番目のものを使用しないことをお勧めします。

+0

あなたは間違っていますが、目的のオブジェクトのメモリは作成前にゼロにされています。それらの構造体メンバをゼロにすることができます。 https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/clm/NSObject/alloc – joerick

+0

ありがとう、知らなかったそれ。一般的なCの構造体割り当てとそれを混ぜ合わせていなければなりません。私の答えを変更しました。 – Tharabas