Cal*_*YSR 21 properties objective-c ivar
我一直无法找到关于这个主题的任何信息,而且我所知道的大部分内容都是完全意外发生的(并且几个小时试图找出我的代码无效的原因).在学习objective-c的大多数教程时,我发现使用相同的名称创建变量和属性.我不明白它的意义,因为看起来该属性完成了所有的工作,变量只是坐在那里.例如:
Test.h
@interface Test : NSObject {
int _timesPlayed, _highscore;
}
@property int timesPlayed, highscore;
// Methods and stuff
@end
Run Code Online (Sandbox Code Playgroud)
Test.m
@implementation Test
@synthesize timesPlayed = _timesPlayed;
@synthesize highscore = _highscore;
// methods and stuff
@end
Run Code Online (Sandbox Code Playgroud)
我知道的
1)好的,今天我发现(经过几个小时的混乱),无论你对属性做了多少改变,highscore = 5091231
当你试图调用[测试高分]时它不会改变任何东西,因为它仍将返回_highscore的值(我认为)是在test.h中设置的ivar.因此,test.m中所有变量的变化都需要改变_highscore而不是highscore.(如果我错了,请纠正我)
2)如果我理解正确(我可能不这样做),test.h中设置的ivars代表实际内存,因为@properties只是访问该内存的方式.因此,在实现之外,我无法通过该属性访问_highscore.
我不明白
基本上我不了解这种情况是我是否需要使用ivars或者我是否可以使用@property和@synthesize.似乎ivars只是额外的代码,除了让我困惑之外什么都不做.我见过的一些最近的tuts似乎没有使用ivars,但有些人做了.那么这只是编码偏好的事情还是实际上很重要?我试过通过Apple的文档搜索,但我在那里相当迷失,似乎永远不会找到我正在寻找的东西.任何指导将不胜感激.
Dav*_*ist 36
您可以将合成属性的语法视为@synthesize propertyName = variableName
.
这意味着如果您编写@synthesize highscore = _highscore;
一个新的ivar,_highscore
将为您创建名称.因此,如果您希望通过转到_highscore
变量来直接访问属性存储的变量.
在某些版本的编译器之前,我不记得合成语句没有创建ivar.相反,它只说它应该使用什么变量,所以你必须声明变量和属性.如果使用下划线前缀合成,那么您的变量需要具有相同的前缀.现在你不必再自己创建变量,而是创建一个variableName
你在合成语句中指定的变量(如果你自己没有声明它,在这种情况下它只是用作后缀变量)财产).
您highscore
在声明变量时显式创建了一个ivar ,然后隐式创建了_highscore
在合成属性时调用的另一个ivar .这些变量不是同一个变量,因此更改其中一个变量不会改变另一个变量.
这真的是一个关于偏好的问题.
有些人认为如果你不必self.
在整个地方写代码,代码就会变得更清晰.人们还说它更快,因为它不需要方法调用(尽管它可能永远不会对您的应用程序性能产生可测量的影响).
更改属性的值将调用所有必需的KVO方法,以便在值更改时通知其他类.默认情况下,对属性的访问也是原子的(不能从多个线程访问),因此从多个线程读取和写入属性更安全(这并不意味着属性指向的对象是线程安全的,如果它是一个可变数组,然后多个线程仍然可以破坏非常糟糕的东西,它只会阻止两个线程将属性设置为不同的东西).
正如您所建议的,您可以只使用@property
和@synthesize
不声明 ivars。上面的问题是您@synthesize
将属性名称映射到编译器生成的新 ivar。因此,出于所有意图和目的,您的类定义现在是:
@interface Test : NSObject {
int timesPlayed;
int highscore;
int _timesPlayed;
int _highscore;
}
...
@end
Run Code Online (Sandbox Code Playgroud)
timesPlayed
如果您通过访问它,则将永远不会直接为 ivar 分配值,self.timesPlayed
因为您没有修改正确的 ivar。
您有多种选择:
1 删除您在原始帖子中声明的两个 ivars,让@property
/ @synthesize
dynamic 二人组做他们的事情。
2 将您的两个 ivars 更改为以下划线“_”为前缀
3 将您的@synthesize
语句更改为:
@implemenation Test
@synthesize timesPlayed;
@synthesize highscore;
...
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
12760 次 |
最近记录: |