为什么人们总是在 Objective-C(即 iPhone)中对实例变量使用重新赋值?

发布于 2024-09-25 06:45:53 字数 276 浏览 5 评论 0原文

我总是在 viewDidLoad 方法中看到示例代码,而不是说,例如

someInstanceVar = [[Classname alloc] init];

它们总是去

Classname *tempVar = [[Classname alloc] init];
someInstanceVar = tempVar;
[tempVar release];

为什么这是?这不是完全相同的事情,只是更长吗?

I always see example code where in the viewDidLoad method, instead of saying, for example

someInstanceVar = [[Classname alloc] init];

they always go

Classname *tempVar = [[Classname alloc] init];
someInstanceVar = tempVar;
[tempVar release];

Why is this? Isn't it the exact same thing, just longer?

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

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

发布评论

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

评论(1

勿忘心安 2024-10-02 06:45:53

简短的回答:这种模式一直出现在 iPhone 代码中,因为它被认为是创建新对象并将其分配给成员变量,同时仍然遵守所有内存管理规则和调用适当的副作用(如果有),同时避免使用自动释放。

详细信息:

您的第二个示例将创建一个僵尸,因为 var 保留着指向已释放内存的指针。更可能的用例如下所示:

tempVar = [[Classname alloc] init];
self.propertyVar = tempVar;
[tempVar release];

假设 propertyVar 被声明为 copyretain 属性,此代码将放弃新属性的所有权反对班级。

更新 1: 以下代码在 iOS 上是等效的,但不推荐*,这可能就是大多数 iPhone 程序使用第一种模式的原因。

self.propertyVar = [[[Classname alloc] init] autorelease];

* autorelease 不鼓励 在 iOS 上,因为过度使用时可能会导致问题。确保您永远不会过度使用它的最简单方法就是永远不要全部使用它,因此您会经常看到使用 alloc/initrelease 的 iOS 代码,即使在 < code>autorelease 是可以接受的。这是编码器偏好的问题。

更新 2: 这种模式一开始看起来很混乱,因为 Cocoa 在幕后自动执行内存管理。这一切的关键是用于设置成员变量的点符号。为了帮助说明,请考虑以下两行代码相同

self.propertyVar = value;
[self setPropertyVar:value];

当您使用点表示法时,Cocoa 将调用指定成员变量的属性访问器。如果该属性已被定义为 copyretain 属性(这是此模式在不创建僵尸的情况下工作的唯一方法),那么会发生一些非常重要的事情:

  1. 之前存储在 propertyVar 中的任何值都会被释放
  2. 新值将被保留或复制
  3. 任何副作用(例如 KVC/KVO 通知)都会自动处理

The short answer: This pattern shows up all the time in iPhone code because it is considered the best way to create a new object and assign it to a member variable while still respecting all of the memory management rules and invoking the appropriate side effects (if any) while also avoiding the use of autorelease.

Details:

Your second example would create a zombie, since var is left holding a pointer to memory that has been released. A more likely usage case looks like this:

tempVar = [[Classname alloc] init];
self.propertyVar = tempVar;
[tempVar release];

Assuming that propertyVar is a declared as copy or retain property, this code hands off ownership of the new object to the class.

Update 1: The following code is equivalent, but not recommended* on iOS, which is probably why most iPhone programs use the first pattern instead.

self.propertyVar = [[[Classname alloc] init] autorelease];

* autorelease is discouraged on iOS because it can cause problems when overused. The easiest way to be sure you never overuse it is to never use it all, so you will quite often see iOS code that uses alloc/init and release, even when autorelease would be acceptable. This is a matter of coder preference.

Update 2: This pattern looks confusing at first because of the memory management that Cocoa performs automagically behind the scenes. The key to it all is the dot notation used to set the member variable. To help illustrate, consider that the following two lines of code are identical:

self.propertyVar = value;
[self setPropertyVar:value];

When you use the dot notation, Cocoa will invoke the property accessor for the indicated member variable. If that property has been defined as a copy or retain property (and that is the only way for this pattern to work without creating a zombie), then several very important things happen:

  1. Whatever value was previously stored in propertyVar is released
  2. The new value is retained or copied
  3. Any side effects (KVC/KVO notifications, for example) are automatically handled
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文