C 结构体的延迟初始化
我不确定如何初始化 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 之前,我可以小心地永远不要访问它,这似乎是由于结构在创建时未定义的事实而引起的。
有“正确”的方法吗?
I'm not sure how to initialize a class property that's a C struct, or pre-iOS5 base type. This is what I'd do if I was dealing with a class, but I don't know what I can check to see if this is the first time the struct has been accessed, since they're undefined at creation:
@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
I realize the primary benefit of lazy initialization is for memory allocation, but if I'm doing this for all the properties that are classes, it seems clearest to use the same style for setting starting values on all my properties.
I can use some other instance variable or property to track whether the self.origin has been accessed, but that seems... not smooth. I could take care to never access self.origin before I've set it, which seems mildly entailed by the fact that structs are undefined at creation.
Is there a "right" way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
objc 类的所有成员在创建时都将初始化为零(甚至是结构体)。我不明白你关于内存分配的观点。该空间是为结构保留的(您没有存储指向它的指针)。无论您是否为其赋值,它都需要相同的空间。
All members of a objc class will be initialized to zero on creation (even a struct). I do not get you point about memory allocation. The space is reserved for the struct (you are not storing a pointer to it). It will require the same space whether you have assigned it a value or not.
通常,您必须具有带内无效状态,例如指针的
nil
。在您的情况下,您可以测试!CGPointEqualToPoint(_origin, CGPointZero)
或!CGPointEqualToPoint(_origin, CGPointMake(-1,-1))
如果您知道这些永远不可能有效的。 (_origin
将默认为CGPointZero
,或者您必须在init
中将其设置为 (-1, -1) if (0, 0) 是有效的。)如果所有可能的带内值都有效,那么您就会遇到您提到的带外标志。
Generally you have to have an in-band invalid state like
nil
for pointers. In your case, you could test!CGPointEqualToPoint(_origin, CGPointZero)
or!CGPointEqualToPoint(_origin, CGPointMake(-1,-1))
if you know those can never be valid. (_origin
will default toCGPointZero
or you'll have to set it to (-1, -1) in aninit
if (0, 0) is valid.)If all possible in-band values are valid, you're stuck with an out-of-band flag as you mentioned.
CGPoint
的惰性计算可以通过(至少)两种不同的方式完成:干净的方式是存储一个
BOOL
,它保留您的是否存在的信息。 CGPoint
已初始化。如果您不想浪费
BOOL
内存,您可以采用肮脏的方法并使用初始值来测试您的
_origin
:但我建议不要使用第二个。
The lazy evaluation of the
CGPoint
could be done in (at least) two different ways:The clean way would be storing a
BOOL
, that keeps the information whether yourCGPoint
has been initialized.In case you do not want to waste a
BOOL
of memory you could do a dirty approachand use an initial value, to test your
_origin
against:But I'd recommend not to use the second one.