我不确定如何初始化一个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,这似乎有点因为结构在创建时未定义。
有“正确”的方式吗?
答案 0 :(得分:5)
objc类的所有成员将在创建时初始化为零(甚至是结构)。我不指你内存分配。该空间是为结构保留的(您没有存储指向它的指针)。无论您是否为其指定了值,它都需要相同的空间。
答案 1 :(得分:0)
通常,您必须有一个带内无效状态,如nil
指针。在您的情况下,如果您知道那些永远无效,您可以测试!CGPointEqualToPoint(_origin, CGPointZero)
或!CGPointEqualToPoint(_origin, CGPointMake(-1,-1))
。 (_origin
将默认为CGPointZero
,或者如果(0,0)有效,则必须在init
中将其设置为(-1,-1)。
如果所有可能的带内值都有效,那么就像你提到的那样,你会遇到一个带外标志。
答案 2 :(得分:0)
CGPoint
的懒惰评估可以(至少)以两种不同的方式完成:
干净的方式是存储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
但我建议不要使用第二个。