Objective c var->;myProperty和var.myProperty

Objective c var->;myProperty和var.myProperty,objective-c,class,variables,object,properties,Objective C,Class,Variables,Object,Properties,我是c目标的新手,我有一些疑问。我看到您可以访问类的属性,如var->myProperty和类似的variable.myProperty,但我不知道这两个类之间有什么区别。我在网上搜索了很多,真的没有找到结论性的答案 对不起,如果我有拼写错误,请提前感谢。查看objective-c中的指针 语法obj->foo访问obj的ivarfoo,而obj.foo访问属性(由@property定义)。主要区别在于obj->foo不使用任何getter/setter,而是直接写入ivar 例如,如果您这样定

我是c目标的新手,我有一些疑问。我看到您可以访问类的属性,如var->myProperty和类似的variable.myProperty,但我不知道这两个类之间有什么区别。我在网上搜索了很多,真的没有找到结论性的答案


对不起,如果我有拼写错误,请提前感谢。

查看objective-c中的指针
语法
obj->foo
访问
obj
的ivar
foo
,而
obj.foo
访问属性(由
@property
定义)。主要区别在于
obj->foo
不使用任何getter/setter,而是直接写入ivar

例如,如果您这样定义属性

@property (atomic, strong, readonly) SomeClass *foo;
现代Objective-C编译器将自动为您创建ivar
\u foo
和属性
foo
(无需声明ivar和
@合成属性)

obj.foo
随后将自动使用
原子
获取程序,并将属性设置为只读(即无setter)。使用ivar语法
obj->\u foo
,您以非原子方式(!)读取属性,甚至可以编写它(请记住,属性是
只读
!)

通常这很简单:总是使用属性语法,除了在
init
dealoc
中使用ivar语法。显然,当您自己实际实现一个getter或setter时,这是另一个使用ivar语法的地方。(感谢@godel9)。(请记住:这是一个粗略的指南,您可能需要直接ivar访问的其他用例)


编辑:由于评论中的一些批评:确实,也可以使用点语法,而无需将某些内容声明为
@property
,例如有些人使用
array.count
而不是
[array count]
(对于
NSArray*array
)但是考虑到OP询问了属性与ivar的关系,这肯定没有被问到。还要注意的是,对于给定的
@property…SomeClass*foo
ivar不一定是
\u foo
,但这将是在最近的ObjC编译器中自动生成的ivar名称(使用
@synthesis
,您可以将属性映射到任意ivar).

有三种情况需要考虑:

  • 使用
    someObject.something

  • 使用
    self->something

  • 使用
    otherObject->something

someObject.something
是点语法。它完全等同于
[someObject something]
在行为方面。它是一个方法调用。请注意,
something
不必通过
@属性声明。也就是说,
someArray.count
someString.length
在语法上都是有效的

self->something
直接访问ivar。这是一种很少使用的语法;很少使用的语法是never。相反,只需使用
something=
[something doSomething]
直接访问ivar即可。无需使用
->

otherObject->something
正在直接挖掘
otherObject
的实例变量。糟糕的程序员。没有甜甜圈。不要这样做。它破坏了封装,导致代码极其脆弱,难以维护


关于
@property
声明的注释。如果您有:

 @property (atomic, strong, readonly) SomeClass *foo;
如果让编译器自动合成所有内容,它将创建一个名为
\u foo
的实例变量


您应该在
init
dealloc
方法中使用直接访问,但是——通常,尽管不总是——在其他任何地方都使用setter/getter。例如,在
init
中,您将执行
\u foo=[SomeClass someClassWithSomeMagicValue:42]
(假设为ARC,因此不需要
保留
).在其他任何地方,你都可以做
[[self-foo]castMagic]

使用ivar语法的另一个地方是自定义getter和setter。显然,这是正确的。在这个答案中有很多错误;ivar访问应该在init/dealoc中使用,而不是在其他任何地方使用。在这种情况下,ivar将是
\u foo
,除非显式合成其他内容。不要求语法仅与
@property
@bbum一起使用您不也需要在自定义getter和setter中使用ivar访问以避免无限循环吗?@BradAllred
self->ivar
不会阻止
self
保留在块中。最后两种情况是相同的。@newacct不完全相同;第二种情况不会破坏封装在上,它正在访问执行该方法的实例的实例变量。在第三种情况下,代码将访问其他对象的iVar,破坏封装。但这不是一个语言概念。这只是一个编程风格问题。@newacct它远远超出了编程风格问题。在像ObjC这样的动态语言有着巨大的成本;它打破了子类化、类别、KVO等。如果你要做
self->
,有人看着你的代码可能会皱起眉毛继续前进。如果你要做
otherObject->
,这个人很可能会在心跳中敲你的门,期待解释至于为什么您正在破坏该语言的标准封装习惯用法。@newacct这不是Java.:)它在Objective-C中绝非罕见;它是一种反模式,使用它会激怒任何经验丰富的ObjC程序员。当Java从ObjC派生出来时,该模式在ObjC中被认为是可以接受的。这在90年代中期发生了变化,因为实现了如何脆弱和僵硬的直接访问生成了最终的代码库。