NSMutableArray对象所有权

时间:2014-06-09 00:20:26

标签: ios objective-c nsmutablearray uitableview

我在TableViewController中有NSMutableArray来保存项目,这些项目显示在TableView中。 NSMutableArray正在viewDidLoad方法中填充。

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self populateItems];
}
- (void)populateItems {
    for (int i = 0; i < numberOfItems; i++) {
        Item *item = [Item createItem];
        [self.items addObject:item];
        item = nil;   // to ensure that newly created object is not pointed by item and only owned by NSMutableArray
    }
}

现在是在索引之间移动行的方法

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
    Item *item = [self.items objectAtIndex:fromIndexPath.row];

    [self.items removeObjectAtIndex:fromIndexPath.row];

    [self.items insertObject:item atIndex:toIndexPath.row];

    [self.tableView reloadData];
}

在这个方法中,我从NSMutableArray获取对象,并在再次将其插入数组之前从NSMutableArray中删除该对象。

我的问题是 - 如果NSMutable是其中对象的唯一所有者 然后从数组中删除它后,没有人应该指向item对象。 因此它本应该被释放但事实并非如此。它已成功插入tableview中。为什么不发生这种情况。

我相信行Item * item = [self.items objectAtIndex:fromIndexPath.row]; 项指针不是fromIndexPath

中出现的对象的所有者

3 个答案:

答案 0 :(得分:1)

以下行声明了对该对象的强引用。

Item *item = [self.items objectAtIndex:fromIndexPath.row];

这允许您将其从阵列中删除并再次插入。

如果由于某种原因你想要项目不是一个强大的参考,你可以这样做:

_weak Item *item = [self.items objectAtIndex:fromIndexPath.row];

答案 1 :(得分:1)

假设您已启用ARC,并且您应启用ARC,则此行代码为:

Item *item = [self.items objectAtIndex:fromIndexPath.row];

将默默地为您保留对象,直到它不再使用。

如果您已禁用ARC,则有三种可能性:

1)除了数组之外的其他东西都保留了对象,这可能是内存泄漏,你应该进一步调查。

2)该对象已被释放,但在该内存位置尚未覆盖任何内容,因此它仍然可以正常工作。呸!这是ARC打算解决的问题类型。

3)Apple可能无法在从阵列中删除后立即释放该对象,这可能是出于性能原因。苹果公司在改善性能和电池寿命方面做了大量无证且经常奇怪的内存管理行为,尤其是在iOS上,他们控制CPU硬件并且不必担心向后兼容性。

总之 - 如果尚未启用ARC,则应启用ARC。而且你不能依赖被“摧毁”的物体。 Apple实际上并没有承诺当一个对象从数组中删除时会被销毁,它们只告诉开发人员他们的代码必须假设它可能已被销毁。

答案 2 :(得分:1)

您有一个本地变量item。默认情况下,变量很强。所以item是一个很强大的变量。只要该变量存在,它将获得保存到它的objets的所有权。

只要存在范围,本地变量才存在。在这段代码中:

-(void) someMethod
{
  NSMutableArray *array1 = [NSMutableArray new];
  {
    NSMutableArray *array2 = [NSMutableArray new];
    [array2 addObject: @"Foo"];
    [array1 addObject: @"Bar"];
  }
  //At this point, array2 no longer exists, so the string "Foo" is deallocated"

  //array1 is still in scope, so the string "bar" still exists
  __weak NSMutableArray *array3;

  //The line below is useless since the array is released as soon as it is created
  array3 = [NSMutableArray new];  
}

NSMutableArray array1在方法的生命周期中存在,因为它的局部变量很强(默认值。)

变量array2也很强大,但它的范围是包围它的设置大括号。一旦你到达结束括号,代码退出该范围,因此变量不再由任何人拥有,并且被释放。

这有帮助吗?