【问题标题】:Memory query: releasing object after adding it to an array内存查询:将对象添加到数组后释放对象
【发布时间】:2012-07-04 17:06:16
【问题描述】:

在下面的代码sn-p中:

NSMutableArray *tmpItemsArray =[[[NSMutableArray alloc] init] autorelease];

while (sqlite3_step(fetch_statement)==SQLITE_ROW){

    int pk =    sqlite3_column_int(fetch_statement,0);  

    Item_A *itemA = [[Item_A alloc] getItemA:pk fromDatabase:db];

    // calculate and set a property of itemA
    [itemA setValue:xValue forkey:xKey];

    // insert into array
    [tmpItemsArray addObject:itemA];
    [itemA release];
}
sqlite3_reset(fetch_statement);

// for each ItemA in array      
    // update itemA in database
for (Item_A *eachItemA in tmpItemsArray) {
    [eachItemA updateItemAInDatabase:db];
}

当我使用 addObject: 方法将对象添加到 tmpItemsArray 时,itemA 指向的内存地址处的对象被添加到数组中。换句话说,tmpItemsArray 中的一个对象指向的内存地址与 ItemA 指向的内存地址相同。

现在当 [itemA release] 执行时,释放内存 -

tmpItemsArray 是否会有指向无效内存的对象

[itemA 释放] 是否仅释放 itemA 对该内存的持有(以某种方式)?

【问题讨论】:

    标签: iphone objective-c


    【解决方案1】:

    release 实际上不会导致内存被释放。相反,它会减少一个计数,该计数表示代码的某些部分保留了对象的次数。分配对象的行为相当于一种保留,而将其添加到数组中则是另一种。您的 release 平衡了 alloc ,此时,数组的保留阻止它被释放。

    当数组消失时,除非发生其他事件,否则它将释放其内容。由于它是一个自动释放的数组,这很可能发生在程序事件循环的下一次迭代中。

    【讨论】:

    • 谢谢菲利普,你解释得很清楚。我对对象的保留计数和实际内存感到困惑。因此,将对象添加到数组会导致其保留计数增加,因此无法释放内存。
    【解决方案2】:

    不,当调用[itemA release] 时,计数器递减并且仅当计数器达到零时才释放内存。每次有人声称拥有该对象的所有权时(例如当输入一个数组时),计数器就会增加。

    【讨论】:

    • 古斯塔夫,感谢您的回复。现在清楚多了。只是一个问题:当我将对象输入数组时,它没有被复制到这里吗?在调试中运行时,我可以看到 ItemA 的地址和添加到 tmpItemsArray 的对象相同。
    • 你是对的,我应该说“每次有人声称拥有所有权”。我按回复编辑。
    猜你喜欢
    • 1970-01-01
    • 2022-01-13
    • 2018-09-06
    • 1970-01-01
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-13
    相关资源
    最近更新 更多