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

nil通常,您必须像指针一样具有带内无效状态。在您的情况下,您可以进行测试,!CGPointEqualToPoint(_origin, CGPointZero)或者!CGPointEqualToPoint(_origin, CGPointMake(-1,-1))如果您知道这些永远不会有效。(如果 (0, 0) 有效,_origin则默认为,CGPointZero否则您必须将其设置为 (-1, -1) 。)init

如果所有可能的带内值都有效,那么您就会遇到前面提到的带外标志。

于 2012-02-12T23:02:21.550 回答
0

的惰性评估CGPoint可以(至少)两种不同的方式完成:

干净的方法是存储 a 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

但我建议不要使用第二个。

于 2012-02-12T23:10:39.443 回答