Objective c var->;myProperty和var.myProperty
我是c目标的新手,我有一些疑问。我看到您可以访问类的属性,如var->myProperty和类似的variable.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 例如,如果您这样定
对不起,如果我有拼写错误,请提前感谢。查看objective-c中的指针
语法
obj->foo
访问obj
的ivarfoo
,而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访问以避免无限循环吗?@BradAllredself->ivar
不会阻止self
保留在块中。最后两种情况是相同的。@newacct不完全相同;第二种情况不会破坏封装在上,它正在访问执行该方法的实例的实例变量。在第三种情况下,代码将访问其他对象的iVar,破坏封装。但这不是一个语言概念。这只是一个编程风格问题。@newacct它远远超出了编程风格问题。在像ObjC这样的动态语言有着巨大的成本;它打破了子类化、类别、KVO等。如果你要做self->
,有人看着你的代码可能会皱起眉毛继续前进。如果你要做otherObject->
,这个人很可能会在心跳中敲你的门,期待解释至于为什么您正在破坏该语言的标准封装习惯用法。@newacct这不是Java.:)它在Objective-C中绝非罕见;它是一种反模式,使用它会激怒任何经验丰富的ObjC程序员。当Java从ObjC派生出来时,该模式在ObjC中被认为是可以接受的。这在90年代中期发生了变化,因为实现了如何脆弱和僵硬的直接访问生成了最终的代码库。