方便的构造函数 ARC 目标 c

Posted

技术标签:

【中文标题】方便的构造函数 ARC 目标 c【英文标题】:Convenient constructor ARC objective c 【发布时间】:2012-12-10 08:37:11 【问题描述】:

我对目标 c 很陌生。 我已经为内存泄漏试验了一个方便的构造函数。

这是我的构造函数

+(Myobject * ) test
    return [[self alloc] init];

我在 main.m 中用这段代码测试它

Myobject * __weak g = [Myobject test];
NSLog(@"%@",g);

我希望日志会显示 (null),因为构造函数中的指针在超出范围时死亡,并且 arc 会从内存中删除该对象,因为没有强指针来保留它。 只是弱指针。

但是在日志中它说一个对象还活着。 在我现在的理解中,有一个强指针可以在构造方法中保留这个对象。所以它会永远存在。

那么我怎样才能摆脱那个指针呢? 还是我错过了什么?

【问题讨论】:

【参考方案1】:

您的test 方法返回一个autoreleased 对象。如果对象没有强引用,则会在当前自动释放池结束时销毁。您可以使用

进行验证
Myobject * __weak g;
@autoreleasepool 
    g = [Myobject test];
    NSLog(@"%@", g); // object still exists here (Correction: might still exist here, see Nikolaus Ruhe's comment)

NSLog(@"%@", g);  // should output "(null)"

由于 ARC 命名约定,如果将方法重命名为 newTest,行为会有所不同。在这种情况下,它会返回一个立即释放的保留对象。

确切的语义可以在Automatic Reference Counting的“3.2.2.保留的返回值”和“3.2.3.未保留的返回值”部分中找到。

更正:正如 Nikolai Ruhe 正确指出的那样,[Myobject test] 返回的对象并不保证在自动释放池中,编译器可以删除 retain/优化期间的释放/自动释放调用。

【讨论】:

+1 很好的解释。次要更正:ARC 不保证对象会进入自动释放池。如果调用和被调用的方法是用 ARC 编译的,那么在优化过程中可能会删除自动释放。 @NikolaiRuhe:谢谢。你是对的,我已将此信息添加到答案中。【参考方案2】:

是的,日志是正确的。正如我所看到的,即使 g 是一个弱引用,但它仍然指向已分配的类对象。此外,g 在这里仍然没有超出范围,因此不存在 ARC 释放它的问题。

【讨论】:

-1 弱引用的思想是可以在指针还存在的时候释放对象。 @Nikolai Ruhe 谢谢你更新我,但你能解释一下这个对象 g 是如何在 autoreleasepool 之外被释放的 好吧,首先:它没有。但 ARC可以立即解除分配对象,因为在 test 返回后没有对它的强引用。 @NikolaiRuhe Myobject __weak *object = [[Myobject alloc] init];给出警告但上面的代码没有 @EvolGate:因为以“alloc”、“copy”、“new”或“init”开头的方法具有不同的语义。正如我在回答中所说,如果test 重命名为newTest,那么它会立即被释放。

以上是关于方便的构造函数 ARC 目标 c的主要内容,如果未能解决你的问题,请参考以下文章

Object 构造函数的方法

ruby ARC 033-Cデータ构造

指针向量的复制构造函数

ARC122C-Calculator乱搞,构造

如何更改 C# Record 构造函数的行为

Objective-C 中的构造函数