2010-03-23 35 views
1

我见过的代码类似的一行浮动约在苹果代码:内存泄漏使用(无效)ALLOC

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

的URLRequest是我自己的自定义类。我没有写这篇文章,我想那个刚刚从苹果公司的例子中拿出来的人。对我来说,这应该泄漏,当我测试它时,我确信它泄漏了16个字节。会吗?我知道如何解决它,但不知道它是从Apple的代码中得到的。

编辑:问题是与SDK,而不是上述代码。请参阅下面的答案以获取更多详细信息

+0

我会/不会/使用任何代码以'-initializeSomething'开始的方法:任何人不知道足够的Objective-C来命名他们的方法'-initSomething'可能不会正确地避免泄漏:可能听起来很刺耳,像这样的一个简单的错误可能实际上表明对工具集不熟悉。 – 2010-03-23 03:53:26

+1

:/虽然你有一个点不是一个挑选?他可能会对缩短单词充满激情。其余的代码不会泄漏 – Rudiger 2010-03-23 04:25:35

+0

Rudiger:遵循适当的命名约定是/总是/一个好主意。 – 2010-03-25 01:04:58

回答

3

想到我可能会更新此版本,因为经过进一步测试以及iOS4发行版发生了变化。

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

有些人可能会想知道为什么要实现这些代码,但它在处理同时运行的代码中的许多不同的NSURLConnections时很有用。

2

完全不知道该代码应该完成什么。它似乎打破了关于初始化方法的每一个约定。从初始化方法返回一个void指针有什么意义?初始化方法的全部要点是返回一个对象。在苹果的代码示例中,你看到了这个吗?

话虽如此,我不明白它为什么会泄漏。由于它不返回对象,因此该方法不会泄露任何内容。有可能是内部泄露的东西。

编辑:

It basically does an NSURLConnection. Because we are submitting a lot of forms with a lot of different values we put it in an external class. All the delegate methods like didFailWithError: are in NSURLRequest and connectionDidFinishLoading just passes the data to its delegate. So it doesn't really need to return anything as it is done through a delegate method.

是的,你需要重新设计这一点。目前,这种方法只是一场等待发生的灾难。如果没有别的,看着这个代码的其他人都会对你在做什么感到困惑。

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

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

这样,您就不必担心泄漏,并且可能会读取您的代码的其他人(包括您自己的月份)都会立即明白代码的作用。

+0

它基本上做一个NSURLConnection。因为我们提交了许多具有很多不同值的表单,所以我们把它放在一个外部类中。像didFailWithError这样的所有委托方法都在NSURLRequest中,而connectionDidFinishLoading只是将数据传递给它的委托。所以它不需要返回任何东西,因为它是通过委托方法完成的。 – Rudiger 2010-03-23 05:00:42

+0

是的。我花了很长时间才弄清楚,然后这个家伙向我展示了Apple从他得到的代码。想想我可能会放弃整个事情并重新开始。 – Rudiger 2010-03-23 23:20:42

2

是的。这是一个漏洞,它可以很容易地通过添加一个自动修复:

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

也许是更好的解决将是创建一个类的功能,这是否:

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

然后,你可以简单地使用[ URLRequest requestWithValues:/ * ... * /]而不调用alloc。

+0

我实际上无法调用autorelease,因为URLRequest中的NSURLConnection可能会在运行循环后响应。我试过了,它崩溃了。我会考虑你的其他修复,因为它听起来更好。 – Rudiger 2010-03-23 07:08:09

+0

@Rudiger,如果您需要实例持久化,那么您应该将其另存为使用它的对象的成员,并在dealloc方法中使用该成员的正常版本。 – 2010-03-23 07:20:09

+0

+1类方法绝对是一种方法 – TechZen 2010-03-23 13:06:14