0

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

@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 に決してアクセスしないように注意することができました。これは、構造体が作成時に未定義であるという事実によって、やや伴うようです。

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

4

3 に答える 3

5

objcクラスのすべてのメンバーは、作成時にゼロに初期化されます(構造体も含む)。私はあなたにメモリ割り当てについて指摘しません。スペースは構造体用に予約されています(ポインターを格納していません)。値を割り当てたかどうかに関係なく、同じスペースが必要になります。

于 2012-02-12T22:51:18.943 に答える
0

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

クリーンな方法は、が初期化されているBOOLかどうかの情報を保持するを保存することです。CGPoint

@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

ただし、2番目のものは使用しないことをお勧めします。

于 2012-02-12T23:10:39.443 に答える
0

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

可能なすべての帯域内値が有効な場合、前述のように帯域外フラグが立ち往生しています。

于 2012-02-12T23:02:21.550 に答える