代码之家  ›  专栏  ›  技术社区  ›  Rudiger

使用(void)alloc的内存泄漏

  •  1
  • Rudiger  · 技术社区  · 14 年前

    我在苹果代码中看到了类似的代码行:

    (void)[[URLRequest alloc] initializeRequestWithValues:postBody url:verifySession httpHeader:nil delegate:self];
    

    urlRequest是我自己的自定义类。我没有写这篇文章,我想是那个从苹果公司的例子中抓到它的人写的。对我来说,这应该会泄漏,当我测试它时,我确信它会泄漏16个字节。会吗?我知道如何修复它,如果它是,但不确定,因为它是从苹果的代码。

    编辑:问题出在SDK上,而不是上面的代码。详情请参阅下面的答案。

    3 回复  |  直到 14 年前
        1
  •  3
  •   Rudiger    14 年前

    我想我可能会在进一步测试和IOS4的发布之后更新它。

    上面的代码不会泄漏,即使在代码迭代200次之后,应用程序的内存占用也会恢复正常。泄漏确实发生在IOS3中,但非常小,在IOS4中,它已经完全消失在模拟器和设备中。

    有些人可能会想知道为什么要实现这段代码,但在处理同时运行的整个代码中的许多不同的nsurlconnections时,它是有效的,并且是有意义的。

        2
  •  2
  •   Michael Aaron Safyan    14 年前

    对。这是一个漏洞,可以通过添加自动释放轻松修复:

    [[[URLRequest alloc] initializeRequestWithValues:postBody url:verifySession httpHeader:nil delegate:self] autorelease];
    

    也许更好的解决方法是创建一个这样做的类函数:

    @interface URLRequest
    {
       // ...
    }
    // ...
    + (void) requestWithValues:/* ... */ 
    // ...
    @end
    

    然后您可以简单地使用[urlrequest requestwithvalues:/*…*/]不调用alloc。

        3
  •  2
  •   TechZen    14 年前

    完全不确定这段代码应该完成什么。它似乎打破了关于初始化方法的每一个约定。从初始化方法返回空指针的意义是什么?初始化方法的整个点是返回一个对象。在苹果的代码示例中,你在哪里看到过这个?

    说了这句话,我不明白为什么会漏。因为它不返回一个对象,所以没有什么可以泄漏到方法外部。内部可能有泄漏。

    编辑:

    它基本上是一个nsurlconnection。 因为我们提交了很多 具有许多不同值的窗体 我们把它放在一个外部类中。全部 委托方法如下 DidfailWitherRor:在nsurlRequest中 连接未完成加载 将数据传递给它的委托。所以呢 不需要归还任何东西 通过代表完成 方法。

    是的,你需要重新设计这个。目前,这种方法只是一种等待发生的灾难。如果没有其他的东西,所有关注这段代码的人都会对你正在做的事情完全困惑。

    如果您不需要保留创建的对象,那么移动它的分配并在一个方法中完全清除。将方法名前缀从“initialize”更改为“setup”、“configure”、“acquire”等,这样名称就不意味着它创建、返回和对象。

    如果您需要一个特定类的一次性实例,请使用类似于Michael Aaron Safyan建议的类方法(同样不要在名称中使用initialize)。类方法应该在内部初始化实例,执行所需的操作,将数据返回到任何位置,然后释放该实例。

    这样,您就不必担心泄漏,其他所有可能阅读您的代码的人(包括您自己几个月)都会立即了解代码的作用。