Objective c Cocoa:指向对象属性的局部变量(双精度)

Objective c Cocoa:指向对象属性的局部变量(双精度),objective-c,ios,cocoa,Objective C,Ios,Cocoa,每隔几个月,我都会尝试重新学习Cocoa,因为除了作为一种爱好,我对iOS编程没有任何实际用途。我将回顾基本知识,看看点符号有什么不同;例如,查看API在默认情况下如何更新以执行常见任务 有大量的文档,这是好的,但当您想要快速启动并运行时,也可能是一件坏事。当它慢慢地回来的时候,我认为自己是一个新生的主体,所以任何帮助都是值得赞赏的。 头文件: @interface FooClass : NSObject { @private double foo; } @property (nona

每隔几个月,我都会尝试重新学习Cocoa,因为除了作为一种爱好,我对iOS编程没有任何实际用途。我将回顾基本知识,看看点符号有什么不同;例如,查看API在默认情况下如何更新以执行常见任务

有大量的文档,这是好的,但当您想要快速启动并运行时,也可能是一件坏事。当它慢慢地回来的时候,我认为自己是一个新生的主体,所以任何帮助都是值得赞赏的。
头文件:

@interface FooClass : NSObject
{
@private
    double foo;
}
@property (nonatomic) double foo;
@end
实施文件:

@implementation FooClass
@synthesize foo = _foo;
- (void) doSomething
{

}
@end
在doSomething实现中,是否可能有一个局部变量(例如,
bar
)作为指向类的
foo
的指针,以便在获取/设置
bar
时更新
foo
(本地别名)?我试过以下几种:

double bar = *self.foo;
double *bar = self.foo;
double *bar = *self.foo;
double *bar = &self.foo;

bar=5;
如果是,正确的语法是什么?还有,有些东西告诉我这是个坏主意,为什么可能呢



编辑:看起来在进一步搜索之后,我发现了类似的东西:现在,我将尝试理解它。

您的示例包含一个错误:

@interface FooClass : NSObject
{
@private
    double foo;
}
@property (nonatomic) double foo;
@end
这声明了一个属性
foo
。它还声明了一个ivar(实例变量)
foo
,可以假定它是与同名属性关联的ivar

@implementation FooClass
@synthesize foo = _foo;
@end
不幸的是,
@synthesis
语句说“合成foo属性并为其创建一个名为
\u foo
的ivar”。因此,现在您有两个ivar,
foo
(您在
@接口中的
{}
之间创建的)和
\u foo
,您刚刚将其合成为与
foo
属性关联的ivar。让
foo
ivar浮在那里是不好的,它是显式声明的,导致读者假设它将与同名的属性相关联,但事实并非如此,因为
\u foo

很久以前,您会被建议修复显式ivar声明,例如

@interface FooClass : NSObject
{
@private
    double _foo;
}
@property (nonatomic) double foo;
@end
但现在更好的是,建议您完全忽略属性的显式ivar定义,让
@synthesis
语句为您创建该ivar,消除我们上面描述的任何问题的可能性,例如:

@interface FooClass : NSObject
@property (nonatomic) double foo;
@end
此外,
@synthesis
语句现在是可选的,如果省略,它将完全按照您的建议执行

在回答关于使用变量访问属性的问题时,这就是
\u foo
实例变量。为什么需要另一个变量?此外,您通常应该使用getter

通常建议使用,而不是使用属性的访问器。该建议也适用于通过局部变量改变财产价值的任何尝试。您唯一绝对应该使用ivar的时间是在您的计算机中

顺便说一下,对的引用是对主要问题的迂回回答(至少如果您曾经尝试使用该局部变量来更改属性的值)。您应该只使用对象设置器访问器来更改属性的值。二传手做了一些重要的事情,忽略这些事情是不明智的。回答您的最后一个问题实际上是指导您如何以不产生编译器警告的方式做错误的事情,因此我不愿意去那里

一些相关参考资料包括:

  • 在《高级内存管理编程指南》中


我发现的文档多种多样。有人说,
@syntheticfoo
将创建一个
foo
的实例变量,另一个说它将创建
\u foo
。所以,我认为具体化不会有什么坏处。我正在尝试重用旧代码来确定发生了什么变化,但我承认,我也在尝试做一些新的事情,这在重新学习时是个坏主意(我以前可能也尝试过做同样的事情,谁知道呢?)。在任何情况下,我都不知道为什么我要为类设置一个私有变量,但是如果我保留
{…}
(我在那里有其他不相关的定义)并删除声明,它还会工作吗?我没有在你的类中涉及私有变量,但是新出现的惯例是在你的.m文件中定义那些。如果你使用的是旧代码,你必须下定决心,但是我上面的回答基本上总结了当前的传统思维(have属性、使用下划线合成ivar、不显式声明属性的ivar、更改属性时使用setter等).至于您希望从旧代码中删除多少旧做法,这取决于您。如果出于任何原因必须接触旧代码,我会非常积极地清理旧代码,因为这通常只会使代码更易于维护,但完全取决于您。@vol7ron:“一个说
@synthetic foo;
将创建
foo
的实例变量,另一个说它将创建
\u foo
”可能不是;事实是
@synthetic foo
将创建名为
foo
的实例变量,而隐式合成(即根本不说
@synthetic foo
)将创建一个名为
\u foo
的实例变量,就像您说的
@synthetic foo=\u foo;
@Rob:我更喜欢您的第一条(已删除)注释。尤其是因为您的“无意冒犯”邀请不必要的降级。我意识到这是一个错误,因此将其带到这里的原因,但您应该意识到它主要是曾经有效的语法,并且在几年前不是一个错误(除了一些新的添加).不用担心,我感谢所有的帮助。我曾经是IRC频道的常客,但我认为这是一个足够简单的问题,可以发布在上面。看起来我不能依赖它了