2

我有以下代码,想知道当 iOS 重新收集分配的内存时会发生什么。p1 指向的内存是否会在之后自动释放,尽管它​​现在指向不同的内存?而且 p2 指向的内存也会被自动释放,因为 p1 在语义上意味着在开始时指向自动释放的内存?

NSMutableArray *p1 = [NSMutableArray arrayWithCapacity:10];
NSMutableArray *p2 = [[NSMutableArray alloc] init];

// what will happen to the memory p1 and p2 point to
// after the following assignment, and at later stage?
p1 = p2;
4

5 回答 5

5

什么都不会泄露,p1 是一个自动释放的对象,在那种情况下,在你将 p2 分配给 p1 之后,它们都只是指向同一个对象。p1 指向的原始对象由自动释放池管理,当池耗尽时将被释放。ARC与否,假设您稍后发布p2,则不会泄漏。

于 2012-08-14T15:12:46.617 回答
1
NSMutableArray *p1 = [NSMutableArray arrayWithCapacity:10];
NSMutableArray *p2 = [[NSMutableArray alloc] init];

// what will happen to the memory p1 and p2 point to
// after the following assignment, and at later stage?
p1 = p2;

“iOS 正在回收分配的内存”——iOS 从来没有垃圾收集功能。

p1 是指向自动释放对象的指针。

p2 是指向非自动释放对象的指针(您或 ARC 必须稍后释放它以避免内存泄漏)

在 p1 = p2 之后,p1 指向 p2 指向的非自动释放对象。p1 指向的原始对象此时是孤立的。

如果您使用 ARC 功能,则无需执行任何操作。在手动内存管理环境下,您执行[p2 release];[p1 release]; 平衡释放您拥有的已分配对象。

于 2012-08-14T15:22:27.657 回答
1

顺便说一句,如果您将来有这样的问题,可以通过 (a) 对相关类进行子类化来轻松测试;(b) 添加您自己dealloc的记录释放的日志。例如:

@interface TestNSMutableArray : NSMutableArray
@end

@implementation TestNSMutableArray
- (void)dealloc
{
    [super dealloc]; // only needed for non-ARC
    NSLog("%s", __FUNCTION__);
}
@end

然后尝试使用TestNSMutableArray而不是NSMutableArray. 如果你看到你的dealloc,你很好。如果没有,那你就泄密了。

显然您也可以使用 Instruments,但是当我第一次接触 Objective-C 内存处理时,我发现这是一种简单但有用的诊断技术。

于 2012-08-14T15:29:15.653 回答
1

在 ARC 下,你不需要做任何事情 两个对象都会被释放。ARC之外:

NSMutableArray *p1 = [NSMutableArray arrayWithCapacity:10];

返回一个自动释放的值。你不需要释放这个值。然而,这:

NSMutableArray *p2 = [[NSMutableArray alloc] init];

手动保留计数为 1。完成后,您需要释放 p2 的值(然后将其分配给 p1)。

于 2012-08-14T15:13:10.583 回答
-1

首先,这取决于您是否使用 ARC。

使用 ARC:不会有内存泄漏。操作系统将释放 p1 的内存,数组现在将指向与 p2 相同的位置。然后,当 p1 和 p2 消失时(例如当类被释放时),操作系统将释放两个数组的内存。

无 ARC:p1 将被泄露。要修复泄漏,您将需要

[p1 release];

在将 p2 的值分配给 p1 之前。如果在释放类之前没有在这两个数组上调用 release,来自 p2 的内存也将被泄漏。

于 2012-08-14T15:03:40.533 回答