【问题标题】:Retain or copy UIKit elements保留或复制 UIKit 元素
【发布时间】:2012-06-27 19:00:19
【问题描述】:

第一个问题

当一个对象的属性在Objective-C中被保留时,为什么同一个类的第二个实例指向同一个对象?如果您实例化一个新类,那么从逻辑上讲,您会想要一个具有单独属性的单独类。 retain 我知道只增加保留计数,copy 将浅拷贝。

我创建了一个保留NSURLRequest 的类。我初始化了该类的两个实例。更改任何已创建类的属性都会更改它们。当我在该物业上使用副本时,它停止了这样做。然而,在线阅读,它说不可变对象上的copy 本质上是一个浅拷贝,因为你真的不想要一个单独的实体,因为它永远无法更改。在这种情况下,NSURLRequest 是不可变的,那么我的示例是如何通过在不可变对象上调用 copy 来工作的呢?这是我复制它的方式:

- (id)initWithRequest:(NSURLRequest *)request {

    self = [super initWithNibName:nil bundle:nil];
    if (self) {
        _request = [request copy];
    }

    return self;
}

第二个问题

我一直在阅读,对于所有不可变对象,我需要使用 copy,而对于可变对象,请使用 retain(或者现在在 ARC 中,strong)。如果 IBOutlets 是 weak 指针,如果我在没有 Interface Builder 的情况下绘制视图怎么办? UIKit 元素会是 copy 还是 retain/strong

谢谢!

【问题讨论】:

  • 您的第一个问题不清楚,听起来您误解了什么。你能发布一个sn-p来展示你在说什么吗?你的第二个问题有一个不正确的概括——通常你对具有可变子类(NSStringNSArray)的类使用copy,对其他问题使用retain/strong。此外,UIResponder 及其子类(构成 GUI 元素)通常不实现 NSCopying,因此不能在 copy 属性中使用。
  • 我重写了我的第一个问题。我明白了你对我第二次的回答,谢谢。
  • 抱歉,还不是很清楚。你“叫”了什么“两次”? “更改任何已创建类的属性”——您的意思是“已创建 instances”?您是否将一个实例的属性设置为指向 NSURLRequest 的新实例,或者您是否将所有实例设置为 same NSURLRequest 对象然后更改它? Small, Self-contained Example 在这里真的很有帮助。

标签: objective-c cocoa-touch memory-management properties uikit


【解决方案1】:

retain 告诉 iOS 不要释放该内存,即使原始属性或指针将自身设置为 nil 也会减少保留计数。因此,如果您执行浅拷贝,将一个指针分配给现有对象,它将保留它。如果你需要做一个深拷贝,那么你应该指定拷贝或者创建一个拷贝构造函数。

弱引用类似于在一块您不想增加保留计数的内存上使用旧的“分配”方法。在某些情况下,您可以有循环引用并且可能永远不会释放内存。如果你不使用 IB 创建 UIKit 对象,假设你有一个指向该对象的有效指针,ARC 肯定会为你保留内存。例如,如果您有一个 UIButton 指针作为视图控制器的成员并且您动态创建一个按钮,只要该指针有效,它将保留该内存,并在指针设置为 nil 时释放它。

【讨论】:

  • 哦,好吧。请参阅我的第一个问题编辑。至于第二个问题,谢谢你的回答。所以一般来说,如果我保留一个 UIKit 元素并在 init 或 viewDidLoad 中分配它,它将在视图的生命周期内保持不变,一旦它被卸载,它会自动将计数减 2 并正确释放它。
  • 如果你对一个对象进行初始化,它的保留计数将为 1,当你需要删除该对象时,你只需调用它的释放来减少保留。也就是说,如果你使用 ARC,你只需要担心指针的生命周期,编译器会为你插入正确的保留和释放
猜你喜欢
  • 2011-08-02
  • 1970-01-01
  • 2020-12-23
  • 2012-03-30
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
  • 1970-01-01
  • 2016-04-19
相关资源
最近更新 更多