Simple Objective-C Memory Question - releasing a property, can't reallocate and init
I'm using this fork of AudioStreamer to stream audio.
In a view controller I have an AudioStreamer as a property:
@property (nonatomic, retain) AudioStreamer *streamer
When the view controller loads I start a stream like this:
self.streamer = [[AudioStreamer alloc] initWithURL:[NSURL URLWithString:preset.url]];
And to stop the stream, release it, and start a new stream I'm doing this:
[streamer stop];
[streamer release];
self.streamer = nil;
self.streamer = [[AudioStreamer alloc] initWithURL:[NSURL URLWithString:preset.url]];
This doesn't work because in the initWithURL: method, there's a check to see if (self != nil)
and that check fails.
Would anyone be able to clarify why this isn't working?
Thanks.
EDIT: It was actually some issues with my project that was causing weird issues. However, I marked an answer as correct beca开发者_Python百科use it had some good memory tips that also helped.
You are overretaining the streamer instance by setting it with the dot syntax and using alloc.
The synthesized setter will retain it once and alloc the second time, you should add an autorelease:
self.streamer = [[[AudioStreamer alloc] initWithURL:[NSURL URLWithString:preset.url]] autorelease];
This line:
self.streamer = [[AudioStreamer alloc] initWithURL:[NSURL URLWithString:preset.url]];
Will automatically release the previously assigned instance for you. So you don't have to call
[streamer release];
self.streamer = nil;
before it.
However you should do
[streamer release];
in your dealloc method.
First of all, you're double-releasing streamer
without intending to.
[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.
And your assignment in the final line is leaking a reference (you're allocing, and then assigning to a retain
property).
You're sort of mixing access metaphors. If you have the property, then use it exclusively:
[self.streamer stop];
self.streamer = [[[AudioStreamer alloc] initWithURL:[NSURL URLWithString:preset.url]] autorelease];
All that said, a failed self != nil
check isn't necessarily explained by this, but it might be, depending on what AudioStreamer is doing for its internal object management.
精彩评论