在 iOS 上的 Objective-C 中,“self.foo”和“self.foo”之间的(风格)差异是什么?和“foo”当使用合成吸气剂时?

发布于 2024-09-14 09:10:05 字数 771 浏览 5 评论 0原文

我搜索了很多关于 ObjC 访问器和合成访问器的问题,但没有结果。这个问题更像是一个“帮我解决问题”的问题;我不期望得到一个答案,但我宁愿寻找专家来权衡这一论点。

在 Cocoa Touch 类中,我会编写一些像这样的代码(其中 soundEffects 是一个合成的 NSArray 属性):

id foo = [self.soundEffects objectAtIndex:1];

一位同事让我解释一下为什么上面的代码比这一行更好:

id foo = [soundEffects objectAtIndex:1];

嗯,从功能上来说,没什么不同。

我对前者的论点如下:

  1. self.soundEffects 告诉所有其他处理该代码的编码人员,这是一个 iVar,而不是本地范围的变量。

  2. 如果需要,我们可以将自定义逻辑放入 soundEffects getter 访问器中。

  3. 没有具体原因,“感觉”是在 Obj-C 工作一年后应该做的正确的事情。

他接受参数 #1 和 #2 为有效,但也给出了对立点:

  1. 这不是代码膨胀吗?

  2. 难道不应该允许一个类直接与它自己的 iVar 对话,而不需要调用它自己的方法(getter)

有接受者吗?

I have searched many questions on ObjC accessors and synthesized accessors to no avail. This question is more of a "help me settle an issue" question; I don't expect one answer, but I'm rather looking for experts to weigh in on the argument.

In a Cocoa Touch class, I would write some code like this (where soundEffects is a synthesized NSArray property):

id foo = [self.soundEffects objectAtIndex:1];

A colleague asked me to explain why the above is any better than this line:

id foo = [soundEffects objectAtIndex:1];

Well, functionally, it's no different.

My arguments for the former are as follows:

  1. self.soundEffects tells every other coder working on the code that this is an iVar, not a locally scoped variable.

  2. If we ever needed to, we could put custom logic in the soundEffects getter accessor.

  3. For no concrete reason, it "feels" like the right thing to do after working in Obj-C for a year.

He accepts arguments #1 and #2 as valid, but also gives the counterpoint:

  1. Isn't this just code bloat?

  2. Shouldn't a class be allowed to talk to its own iVars directly without having to call a method (the getter) on itself?

Any takers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

莳間冲淡了誓言ζ 2024-09-21 09:10:05

我个人决定对 ivars 使用下划线前缀,这样

@synthesize name = _name;

我就不会混淆它们。不使用 self 的主要问题是此代码

_name = ...

非常不同

self.name = ...

与@property 使用保留选项时 。第一个不保留对象,第二个调用保留的合成 setter。

唯一有很大区别的是分配,所以我倾向于一直使用 self. ,所以我确保在分配时这样做。

I have personally settled on using an underscore prefix for ivars, and this kind of synthesize

@synthesize name = _name;

That way I don't mix them up. The major issue with not using self is that this code

_name = ...

is very different from

self.name = ...

When the @property uses the retain option. The first does not retain the object, and the second calls the synthesized setter that retains.

The only time it makes a big difference is with assigning, so I tend to use self. all of the time so I make sure I do it on assigns.

酒儿 2024-09-21 09:10:05

你的观点1不太正确:self.soundEffects不是一个ivar,尽管它可能碰巧给你一些的东西——就像对于您合成的 NSArray 来说,目前确实如此。

这反过来意味着你的第 2 点是问题的关键 - 如果你通过访问器路由所有访问,那么所有内容都被很好地封装,并且你可以稍后随意修改实现,而不必担心副作用。

当您使用 mutator 时,这也是一个很好的实践,因此您可以保持一致的内存管理。

在大多数情况下,我建议通过 self.property 路由所有属于属性的内容,并限制直接 ivar 访问严格内部的内容。然而,我承认在某些情况下——尤其是对于不使用retain/copy语义的东西——它可能更多是一种样式偏好。

Your point 1 is not quite right: self.soundEffects is not an ivar, although it may happen to give you something which is -- as it does in the case of your synthesized NSArray, at the moment.

This in turn implies that your point 2 is the crux of the matter -- if you route all access through the accessor, then everything is nicely encapsulated and you're free to modify the implementation later without having to worry about side effects.

It's also good practice for when you use the mutator, so you maintain consistent memory management.

For the most part, I'd say it's advisable to route through self.property for everything that is a property, and restrict direct ivar access to things which are strictly internal. However, I'll admit that in some cases -- especially for things that don't use retain/copy semantics -- it can be more of a style preference.

蒗幽 2024-09-21 09:10:05

使用诸如 self.variable = nil 之类的东西可以使变量通过其设置器,从而免费管理内存。如果您仅在 dealloc 方法中使用 variable = nil ,则会导致泄漏,因为它实际上并未通过变量的合成 setter 并减少保留计数。请参阅这篇文章自我内存泄漏。

为此原因,建议(我相信)始终使用 self.就内存管理而言,处理您拥有的实例变量时。

using something like self.variable = nil makes the variable go through its setter and therefore gets memory managed for free. if you just use variable = nil for instance in a dealloc method, it will cause a leak since it is not actually going through the synthesized setter for the variable and decreasing the retain count. See this post memory leak with self.

For this reason, it is advisable (i believe) to always use self. when dealing with instance variables that you own as far as memory management is concerned.

辞旧 2024-09-21 09:10:05
self.soundEffects

sets/gets the instance variable through the setter/getter, and hence if we want to do some custom operations when their value changes, that logic can go in their getter/setter.

同样根据 ios 6,对应的 ivar

@property (nonatomic)NSArray *propertyName;

将是

_propertyName

所以我猜你不能使用

id foo = [soundEffects objectAtIndex:1];

anymore.Not sure though.Instead you should use

id foo = soundEffects[1];

self.soundEffects

sets/gets the instance variable through the setter/getter, and hence if we want to do some custom operations when their value changes, that logic can go in their getter/setter.

Also as per ios 6, the ivar corresponding to

@property (nonatomic)NSArray *propertyName;

will be

_propertyName

so i guess you cant use

id foo = [soundEffects objectAtIndex:1];

anymore.Not sure though.Instead you should use

id foo = soundEffects[1];

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文