gpt4 book ai didi

objective-c - 局部变量 objective-c 中的内存管理

转载 作者:搜寻专家 更新时间:2023-10-30 20:02:47 24 4
gpt4 key购买 nike

在一次采访中,我被要求实现 NSArray 的 exchangeObjectAtIndex:withObjectAtIndex: 方法。我写了下面的代码:

- (void)exchangeObjectAtIndex:(NSUInteger)index1 withObjectAtIndex:(NSUInteger)index2 {
id tmp = [self objectAtIndex:index1];
[self replaceObjectAtIndex:index1 withObject:[self objectAtIndex:index2]];
[self replaceObjectAtIndex:index2 withObject:tmp];
}

面试官说第一行有内存管理问题,我要抓bad_access_exc。他建议这样写:

- (void)exchangeObjectAtIndex:(NSUInteger)index1 withObjectAtIndex:(NSUInteger)index2 {
id tmp = [[[self objectAtIndex:index1] retain] autorelease];
[self replaceObjectAtIndex:index1 withObject:[self objectAtIndex:index2]];
[self replaceObjectAtIndex:index2 withObject:tmp];
}

我知道他的代码是对的,但是因为 tmp 是局部变量,而且会被赋值,所以没有释放,一切都会好起来的。有没有错误?

最佳答案

如果您使用手动内存管理,则会出现错误。 Apple 已将问题记录在 “Avoid Causing Deallocation of Objects You’re Using” in the Advanced Memory Management Programming Guide 下.

具体来说,objectAtIndex: 不会保留自动释放 它返回给您的对象。所以 NSArray 可能拥有对该对象的唯一“拥有”引用。在手动保留计数 (MRC) 下分配给 tmp 不会保留该对象,因此 tmp 不拥有它,自动释放池也不拥有它。

这意味着当您的方法的第 2 行发送 [self replaceObjectAtIndex:index1 withObject:[self objectAtIndex:index2]] 时,数组可能会释放对该对象的最后引用,从而释放它。那时,tmp 指的是一个释放的对象;这称为“悬挂引用”。

然后在第 3 行中,您尝试将悬挂引用放入数组中。该数组会将 retain 发送到引用,这是无效的,您将崩溃或遇到堆损坏。

在 ARC 下,分配给 tmp 确实保留对象,所以在这种情况下没有错误。

关于objective-c - 局部变量 objective-c 中的内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17757499/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com