1

我需要对以下代码进行一些说明。

我有一个包含 ClassA 对象的数组。然后我检索其中一个对象并将其分配给局部变量 object1。

 ClassA object1 = [ClassAObjectContainer objectAtIndex:0];

(Q.1 - 这增加保留计数吗??我认为不是)

现在我删除对象

  [ClassAObjectContainer removeObjectAtIndex:0];

( Q.2 - 所以现在 object1 指向已释放的实例??如果我向它发送消息,它会崩溃吗??

所以我应该使用 ClassA object1 = [[ClassAObjectContainer objectAtIndex:0] retain]; 如果我想保持对象活着并稍后使用它。

另一件事,当从方法返回对象时,哪种方法更好

- (ClassA *)calle
{
    ClassA *object1 = [[ClassA alloc] init];
    return [object1 autorelease];
}

- (void)Caller
{
    ClassA *object2 = [self calle];
    //now suppose object1 is auto-released, so in this case object2 points to deallocated instance?
}

所以不应该更好吗-

- (void)CallerMethod
{
    ClassA *object2 = [[self calle] retain];
   // Do other works.
   /.....

    [object2 release];
}

在这种情况下发生的另一件事,

- (ClassA *)calle2
    {
        ClassA *object1 = [[ClassA alloc] init];
        return [object1 autorelease];
    }


 - (void)CallerMethod
    {
        ClassA *object2 = [self calle];

        object2 = [self calle2];

    }

这里是否有内存泄漏,或者由于 ClassA *object2 = [self calle] 是弱/赋值,在第二次初始化 object2 = [self calle2] 后没有问题,我们可以这样分配 100 个对象,不会发生内存泄漏。

谢谢你的时间。

4

2 回答 2

3

以下是答案

Q1:没有。对于简单赋值,retainCount 不会有任何变化。

Q2:它取决于Index处对象的ratainCount,即当它从数组中删除时,其retainCount将减1。如果retainCount在删除后变为0,则会导致崩溃,否则不会。

AutoRelease:使用方法(除了 new/copy)返回的自动释放对象时的黄金法则是保留它。一旦工作完成,你应该释放它。您可以根据需要进行尽可能多的初始化,但它可能会在创建的所有对象时使自动租赁池过载。

于 2013-02-18T06:35:43.110 回答
2

Q.1 - 这会增加保留计数吗?我认为不是

不一定,但它可能会暂时增加它。在返回对象之前执行objectAtIndex:canretainautorelease对象,这将是一件非常友好的事情,因为......

Q.2 - 那么现在 object1 指向已释放的实例??如果我向它发送消息,它会崩溃吗?

如果-objectAtIndex:不注意返回如上所述的自动释放对象,它可能会。如果有任何疑问,您应该在将其从容器中取出之前自己保留该对象。因此,例如,文档-[UIView removeFromSuperView]说:

如果您打算重用视图,请确保在调用此方法之前保留它,并在以后酌情再次释放它。

那正是因为superview会释放视图。如果您没有保留它,它可能会在那时被释放。

所以我应该使用 ClassA object1 = [[ClassAObjectContainer objectAtIndex:0] retain]; 如果我想保持对象活着并稍后使用它。

当然,如果您想“以后”使用它,您应该保留它。如果您要“现在”使用它,那么您可能不需要保留该对象,这取决于(再​​次)ClassAObjectContainer它所说的内容。

我不确定我是否遵循您的其余问题。但是,一般来说,当您从其他方法取回一个对象时,您应该能够使用该对象而不保留它,除非您打算在接收它的方法结束后保留​​它。所以,如果你将它分配给一个实例变量或其他东西,你应该通过调用来获得对象的所有权retain。集合的行为使事情变得有点复杂——如果你从集合中获取一个对象,然后告诉该集合删除该对象,那么如果在删除后需要它,你真的应该首先保留该对象. 另一方面,如果您使用 ARC(为什么不使用呢?),您不必担心这些事情。

于 2013-02-18T06:35:42.037 回答