Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 访问IVAR与使用访问器有什么直接区别?_Objective C - Fatal编程技术网

Objective c 访问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函数访问属性的快捷方式,并且它总是使用这些函数。如果没有具有该名

因此,在我看到的一些代码中,它们直接访问对象ivar,而不是使用访问器。使用它们而不是访问器有什么好处

那么这将如何实现呢

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