【问题标题】:Objective-C malloc with c array of arrayObjective-C malloc 与 c 数组数组
【发布时间】:2012-09-06 19:19:53
【问题描述】:

我在视图中有一个属性,这样的数组数组:

@interface MyView : UIView

@property (nonatomic) CGPoint **matrix;

@end

在拥有此视图的控制器中,我已在 -viewDidLoad 中加载数据并在 -viewDidUnload 中释放内存,如下所示:

- (void)viewDidLoad
{

    self.myView.matrix = malloc(sizeof(CGPoint*) * array1Size);
    for (int k = 0; k < array1Size; k++) {
        self.myView.matrix[k] = malloc(sizeof(CGPoint) * innerArraySize);
    }
}

- (void)viewDidUnload
{
    for (int k = 0; k < array1Size; k++) {
        free(self.myView.matrix[k]);
        self.myView.matrix[k] = nil;
    }
    free(self.myView.matrix);
    self.myView.matrix = nil;
    [self setMyView:nil];
    [super viewDidUnload];
}

在进行分析时,我在这里看到了泄漏。有人可以帮我解决我的错误吗?

谢谢

更新

我尝试从 viewDidUnload 中删除免费代码并像这样使用 dealloc:

-(void)dealloc {
    [self freeArray];
}

- (void) freeArray {

    for (int k = 0; k < 5; k++) {
        free(self.myView.matrix[k]);
        self.myView.matrix[k] = NULL;
    }

    free(self.myView.matrix);
    self.myView.matrix = NULL;
}

然后我将初始化代码嵌入:

if (self.graphView.matrix == NULL) {
    ...
}

现在不再泄漏,谢谢!

【问题讨论】:

  • 您的代码看起来不错(除了分配nil 而不是NULL,机器人几乎是一回事)。您可以跳过循环内的赋值,因为数组即将被释放。你确定你的viewDidUnload 被调用了吗?
  • -viewDidUnload 已弃用,您不应使用它。您需要将此代码移至您的 -dealloc 方法。此外,-viewDidUnload 只有在视图完全被另一个视图控制器的视图遮挡时才会在某些内存压力情况下被调用。当视图控制器被简单地释放时,它不会被调用。虽然自动装箱很烦人,但使用 Foundation 集合而不是指针可能更容易。
  • 我不能使用 dealloc,因为我正在使用 ARC 进行内存管理。谢谢
  • @JasonCoco viewDidUnload可能会被弃用,如果未来的 iOS 版本仍处于 NDA 下将放弃视图卸载。
  • 在 ARC 下使用 dealloc 是完全有效且常见的。

标签: objective-c ios c memory-management memory-leaks


【解决方案1】:

您的代码不能确保矩阵的每个设置都与一个拆解匹配。例如,viewDidUnload 不能保证被调用。此外,您无法防止重复设置或拆除。

如果您确实需要 C 数组数组,更好的方法是在视图的初始化程序(initWithFrame:initWithCoder:)中创建它并在其 dealloc 中删除它。

编辑:为了减轻您对 dealloc 和 ARC 的担忧:

您当然可以在 ARC 中覆盖 dealloc 并依赖它被调用。唯一的区别是您不能显式地调用被覆盖的实现 ([super dealloc])。 ARC 会为您插入。

【讨论】:

  • 我不能使用 dealloc,因为我正在使用 ARC 进行内存管理。而且我想使用结构数组来提高性能。可能我必须找到一个更好的地方来处理项目?谢谢
  • 我还建议直接使用 CGPoint 结构数组来避免所有额外的 malloc/free 流量。它还占用更少的内存并且总体使用速度更快(双浮点结构比传递对双浮点结构的引用然后通过间接访问内容要快)。
  • 你当然可以在 ARC 中使用dealloc!正是因为需要释放非 ARC 托管资源,才会调用它。
  • 我尝试使用 dealloc,但分析泄漏仍然存在。你能给我一个例子,说明“直接使用 CGPoint 数组”的含义吗?
  • @Guaido79 在初始化属性之前,您一定要确保 `(self.myView.matrix == NULL)。
【解决方案2】:

使用 CGPoint 数组:

@property (nonatomic) CGPoint *matrix;

.... init ...
{
   ...
   matrix = (CGPoint*) malloc(arraySize * sizeof(CGPoint));
 ...
}

- (void) dealloc
{
    free(matrix);
}

然后您只需在数组中直接设置/获取 CGPoint 结构:

CGPoint someCGPoint = {0,0};
matrix[i] = someCGPoint;

someCGPoint = matrix[i];

这将比 CGPoint** 更快,内存效率更高。你的泄漏已经消失了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多