Objective c 访问IVAR与使用访问器有什么直接区别?
因此,在我看到的一些代码中,它们直接访问对象ivar,而不是使用访问器。使用它们而不是访问器有什么好处 那么这将如何实现呢Objective c 访问IVAR与使用访问器有什么直接区别?,objective-c,Objective C,因此,在我看到的一些代码中,它们直接访问对象ivar,而不是使用访问器。使用它们而不是访问器有什么好处 那么这将如何实现呢 thing = object->ivar 与此不同 thing = object.ivar 谢谢。这是c/c++和objective-c之间存在巨大差异的一件事 在C/C++中,直接访问变量,->如果是指向变量的指针,则访问变量,因此基本上是相同的 在Objective-C中,是使用setter和getter函数访问属性的快捷方式,并且它总是使用这些函数。如果没有具有该名
thing = object->ivar
与此不同
thing = object.ivar
谢谢。这是c/c++和objective-c之间存在巨大差异的一件事 在C/C++中,
直接访问变量,->
如果是指向变量的指针,则访问变量,因此基本上是相同的
在Objective-C中,
是使用setter和getter函数访问属性的快捷方式,并且它总是使用这些函数。如果没有具有该名称的属性,则无法使用它访问ivars
有人说允许直接访问变量是“肮脏的”。如果有更多的人在代码上工作,那么使用访问器就“更干净”,因为在变量发生变化的地方调试可能更容易,因为您可以随时中断setter
你甚至可以用它做“坏事”,比如:
NSArray *array = [NSArray alloc] init];
int count = array.count;
array.release;
这在技术上是可行的,因为
array.release
是[array release]
的快捷方式,但将
用于其他对象而不是属性是不好的方式。所有IVAR都是私有的。无法直接从对象外部访问它们。因此,用ObjC术语来说,两个代码示例是等效的
当您调用object.ivar
时,您真正要做的是调用object
的ivar
选择器。这可能是您自己编写的getter方法,也可能是您使用@synthesis
创建的合成getter方法
然而,这个东西是一个ivar。您的代码将调用object
上的ivar
选择器,并将结果直接分配给实例的对象
如果您将其编写为self.thing=object.ivar
,那么您将使用实例的setter方法分配给thing
在ObjC中使用访问器(特别是合成属性)的一些优点是符合KVO/KVC;更好的并发支持;访问控制(只读、读写);以及访问器在任何其他OO语言中为您提供的所有优势。属性的优势在于它们调用与您的IVAR一起工作的方法,而不是直接调用IVAR,因此您可以执行以下操作:
-(void)setFrame:(CGRect)frame
{
if([self frameIsValid:frame])
{
if(self.flipsFrames)
{
frame.size = CGSizeMake(frame.size.height,frame.size.width);
}
[super setFrame:frame];
[delegate viewSubclass:self ChangedFrameTo:frame];
}
}
这里显示的四个优点是:
- 超越的可能性
- 检查给定值的可能性
- 改变给定值的可能性(小心使用)
- 对电话作出反应的一种方式
另一个优点是:
-(NSInteger) amountOfMinutes
{
return amountOfSeconds * 60;
}
您可以对多个属性使用1个ivar,节省内存并防止/减少冗余,同时保留有用的不同格式
使用IVAR并没有什么好处,除非您不想使用属性,这样您的类就更加封装了。这并不是说它不可能达到,但它清楚地表明它不应该达到。首先让我说,我完全讨厌Objective-C点符号。它为了简洁而牺牲了可理解性,这是一件坏事。事实上,这里的另外两个答案都显示了点符号所引入的那种混淆的证据
我已经把这番咆哮置之不理了,现在试着回答这个问题
在引擎盖下,Objective-C对象被实现为指向C结构的指针。这就是为什么
obj->ivar
有时是有效的。考虑到它是一个C结构
(*obj.ivar)
也应该完全按照您对C的期望工作。话虽如此,您可以将IVAR设置为私有或受保护,在这种情况下,在IVAR可见的范围之外使用上述内容将导致编译器错误
点运算符应用于Objective-C对象(这是一个指针,请不要忘记)时具有完全不同的含义。它是向对象发送访问器消息的语法糖,意思是:
foo = obj.property;
obj.property = foo;
与相同
foo = [obj property];
[obj setProperty: foo];
这就是点表示法的全部内容。如果您通过代码将第一种形式的所有实例更改为第二种形式的实例,那么您已经完成了编译器使用点表示法所做的一切
特别是
- 使用点表示法不需要声明的
@属性
。您可以以传统的方式将set和get访问器声明为Objective C方法,尽管对于逻辑上属于属性的事物使用@property
声明无疑是最佳实践
- 您不需要备份实例变量。你的getter和setter没有理由不能计算值
综上所述,obj->ivar
和obj.ivar
之间的主要区别在于前者直接修改ivar,后者调用访问器,这意味着后者可以执行所需的任何内存管理工作(保留、释放、复制等),还可以调用键值 这个答案有很多地方不对劲。最糟糕的是,点表示法与属性无关。只要访问器存在,就可以使用它。另外,既然数组的元素计数什么时候不是数组的属性?计数不是数组的属性,也许您应该在向下表决之前检查它?属性是Objective-C2.0的特性,所以它只是一个函数。如果你不相信,你可以查一下NSArray.h。还可以检查@Bastian,这是出乎意料的,但是随着后面属性的引入,这是有意义的。count是一个有点混乱的例子,但是,您添加的版本更清晰。无论如何,我会删除我的第一条评论,但我会保留否决票,直到删除或证明“据我所知,你不能把所有东西都放在属性中…”为止。据我所知,正确使用retain和assig