2011-05-25 35 views
0

我正在使用这个分支的AudioStreamer来传输音频。简单的Objective-C内存问题 - 释放一个属性,不能重新分配并初始化

在一个视图控制器我有一个AudioStreamer作为一个属性: @property (nonatomic, retain) AudioStreamer *streamer

当视图控制器负载我开始这样的流:

self.streamer = [[AudioStreamer alloc] initWithURL:[NSURL URLWithString:preset.url]];

并停止流,释放它,并开始一个新的流我这样做:

[streamer stop]; 
[streamer release]; 
self.streamer = nil; 
self.streamer = [[AudioStreamer alloc] initWithURL:[NSURL URLWithString:preset.url]]; 

这不起作用因为在initWithURL:方法中使用,有一个检查看到if (self != nil)并且检查失败。

任何人都可以澄清为什么这是行不通的?

谢谢。

编辑:这实际上是我的项目造成奇怪的问题的一些问题。但是,我标记了一个正确的答案,因为它有一些很好的记忆提示,这些提示也有帮助。

+0

你能告诉我们initWithURL方法的代码吗? – 2011-05-25 20:49:04

+0

有什么症状导致您认为问题出现在'initWithURL:'调用中?关于这种方法没什么特别之处,'AudioStreamer'超级就是'NSObject',所以'[super init]'不太可能失败。 – 2011-05-25 20:53:16

+0

我对AudioStreamer类做了一个简短的介绍,如果初始化器在你的fork中是一样的,那么我实际上不知道它为什么会失败,这个类只是从NSObject继承而来,而initWithURL根本就没有做任何事情。 – 2011-05-25 20:54:34

回答

3

通过使用点语法和使用alloc设置,您正在过度维护流实例实例。

合成的二传手将保留一次或Alloc第二次,你应该添加一个自动释放:

self.streamer = [[[AudioStreamer alloc] initWithURL:[NSURL URLWithString:preset.url]] autorelease]; 

这条线:

self.streamer = [[AudioStreamer alloc] initWithURL:[NSURL URLWithString:preset.url]]; 

会自动释放先前分配的实例为您服务。因此,您不必拨打

[streamer release]; 
self.streamer = nil; 

之前。

但是你应该在你的dealloc方法做

[streamer release]; 

+0

+1,很好。没有注意到他过度保留(除了不正确的释放)。 – DarkDust 2011-05-25 20:53:36

3

首先,你没有打算双重释放streamer

[streamer release];  // Releases the ivar, but doesn't set it to nil. 
self.streamer = nil; // This is a property access, which releases the old 
         // value (again) before setting to nil. 

,并在最后一行的分配泄漏的引用(你allocing,然后分配到retain属性)。

你有点混合访问隐喻。如果你有属性,那么只使用它:

[self.streamer stop]; 
self.streamer = [[[AudioStreamer alloc] initWithURL:[NSURL URLWithString:preset.url]] autorelease]; 

所有这一切说,失败的self != nil检查并不一定是由这个解释,但也可能是,这取决于AudioStreamer正在为它的内部对象管理。