在目标 c 中使用 ivars 与属性的原因 [英] Reason to use ivars vs properties in objective c

查看:18
本文介绍了在目标 c 中使用 ivars 与属性的原因的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直无法找到有关此主题的任何信息,而且我所了解的大部分信息完全是偶然的(并且花了几个小时试图找出我的代码无法正常工作的原因).在学习 Objective-c 时,我发现大多数教程都使用相同的名称创建变量和属性.我不明白其中的意义,因为似乎该属性完成了所有工作,而变量就在那里.例如:

I have been unable to find any information on this topic and most of what I know about it has come by complete accident (and a few hours of trying to figure out why my code wasn't working). While learning objective-c most tutorials I have found make variables and properties with the same name. I don't understand the significance because it seems that the property does all the work and the variable just kind of sits there. For instance:

Test.h

@interface Test : NSObject {
    int _timesPlayed, _highscore;
}

@property int timesPlayed, highscore;

// Methods and stuff

@end

Test.m

@implementation Test

  @synthesize timesPlayed = _timesPlayed;
  @synthesize highscore   = _highscore;

  // methods and stuff

@end

我所知道的

1) 好吧,今天我发现(经过数小时的困惑)无论您对属性 highscore = 5091231 做了多少更改,当您尝试调用 [test highscore] 因为它仍然会返回 _highscore 的值,它(我认为)是在 test.h 中设置的 ivar.所以 test.m 中所有变量的变化都需要改变 _highscore 而不是 highscore.(如果我错了,请纠正我)

1) Okay so today I found out (after hours of confusion) that no matter how much changing you do to the properties highscore = 5091231 it won't change anything when you try to call [test highscore] as it will still be returning the value of _highscore which (I think) is the ivar that was set in test.h. So all changing of variables in test.m needs to be changing _highscore and not highscore. (Correct me if I'm wrong here please)

2) 如果我理解正确(我可能不理解),在 test.h 中设置的 ivars 代表实际内存,而 @properties 只是访问该内存的方法.所以在实现之外我无法访问 _highscore 而不通过属性.

2) If I understand it correctly (I probably don't) the ivars set in test.h represent the actual memory where as the @properties are just ways to access that memory. So outside of the implementation I can't access _highscore without going through the property.

我不明白的地方

基本上我不明白这种情况是我是否需要使用 ivars 或者我是否可以只使用 @property 和 @synthesize.似乎 ivars 只是额外的代码,除了让我感到困惑之外什么也没做.我最近看到的一些 tuts 似乎没有使用 ivars,但有些却使用了.那么这只是编码偏好还是它实际上很重要?我曾尝试搜索 Apple 的文档,但我在那里迷失了方向,似乎从未找到我要找的东西.任何指导将不胜感激.

Basically what I don't get about this situation is whether or not I need to use the ivars at all or if I can just use @property and @synthesize. It seems like the ivars are just extra code that don't really do anything but confuse me. Some of the most recent tuts I've seen don't seem to use ivars but then some do. So is this just a coding preference thing or is it actually important? I have tried searching through Apple's Documentation but I get rather lost in there and never seem to find what I'm looking for. Any guidance will be greatly appreciated.

推荐答案

您可以将合成属性的语法视为 @synthesize propertyName = variableName.

You can think of the syntax for synthesizing properties as @synthesize propertyName = variableName.

这意味着如果您编写 @synthesize highscore = _highscore; 一个名为 _highscore 的新 ivar 将为您创建.因此,如果您愿意,可以通过转到 _highscore 变量来直接访问存储属性的变量.

This means that if you write @synthesize highscore = _highscore; a new ivar with the name _highscore will be created for you. So if you wanted to you could access the variable that the property is stored in directly by going to the _highscore variable.

在某些版本的编译器之前,我不记得综合语句没有创建 ivar.相反,它只说明应该使用哪个变量,因此您必须同时声明变量和属性.如果您使用下划线前缀进行合成,那么您的变量需要具有相同的前缀.现在您不必再自己创建变量,而是会创建一个带有您在综合语句中指定的 variableName 的变量(如果您还没有自己声明它,在这种情况下只是用作属性的后备变量).

Prior to some version of the compiler that I don't remember the synthesis statement didn't create the ivar. Instead it only said what variable it should use so you had to declare both the variable and the property. If you synthesized with a underscore prefix then your variable needed to have the same prefix. Now you don't have to create the variable yourself anymore, instead a variable with the variableName that you specified in the synthesis statement will be created (if you didn't already declare it yourself in which case it is just used as the backing variable of the property).

您在声明变量时显式创建一个名为 highscore 的 ivar,然后在合成属性时隐式创建另一个名为 _highscore 的 ivar.这些不是同一个变量,所以改变其中一个不会改变另一个.

You are explicitly creating one ivar called highscore when declaring the variable and then implicitly creating another ivar called _highscore when synthesizing the property. These are not the same variable so changing one of them changes nothing about the other.

这确实是一个关于偏好的问题.

This is really a question about preference.

有些人觉得如果你不必到处写self.,代码会变得更简洁.人们还说它更快,因为它不需要方法调用(尽管它可能永远不会对您的应用性能产生可衡量的影响).

Some people feel that the code becomes cleaner if you don't have to write self. all over the place. People also say that it is faster since it doesn't require a method call (though it is probably never ever going to have a measurable effect on your apps performance).

更改属性值将调用所有必要的 KVO 方法,以便在值更改时通知其他类.默认情况下,对属性的访问也是原子的(不能从多个线程访问),因此从多个线程读取和写入属性更安全(这并不意味着该属性指向的对象是线程安全的,如果它是一个可变数组,那么多个线程仍然可以破坏非常糟糕的事情,它只会阻止两个线程将属性设置为不同的东西).

Changing the value of the property will call all the necessary KVO methods so that other classes can get notified when the value changes. By default access to properties is also atomic (cannot be accessed from more then one thread) so the property is safer to read and write to from multiple thread (this doesn't mean that the object that the property points to is thread safe, if it's an mutable array then multiple thread can still break things really bad, it will only prevent two threads from setting the property to different things).

这篇关于在目标 c 中使用 ivars 与属性的原因的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆