Closed GoogleCodeExporter closed 9 years ago
Shai, I have been looking into this and have made some interesting discoveries.
I ran the attached test app through the debugger with instruments, and did not
observe any memory leak associated with the sounds, however, it was clear there
was a resource leak as the sound resources were not being let go.
The ultimate error when it crashes is caused by a "too many open files"
message. Also, the allocations section shows numerous in memory sound objects
that had been allocated but never released.
Looking at the dealloc code, the audio player is clearly getting released - but
the allocations was still showing a reference count of 1.
The problematic file is AudioPlayer.m, with the AudioPlayer interface. Here
are the two constructors:
(id)initWithURL:(NSString*)url callback:(void*)callback {
self = [super init];
if (self) {
runnableCallback = callback;
errorInfo = nil;
playerInstance = nil;
avPlayerInstance = nil;
if(currentlyPlaying == nil) {
currentlyPlaying = self;
}
if ([url hasPrefix:@"http"]) {
avPlayerInstance = [[AVPlayer alloc] initWithURL:[NSURL URLWithString:url]];
avPlayerInstance.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[avPlayerInstance currentItem]];
[avPlayerInstance retain];
} else {
playerInstance = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:url] error:&errorInfo];
playerInstance.delegate = self;
if(volume > -1) {
playerInstance.volume = volume;
}
[playerInstance retain];
}
}
return self;
}
- (id)initWithNSData:(NSData*)data callback:(void*)callback {
self = [super init];
if (self) {
runnableCallback = callback;
playerInstance = [[AVAudioPlayer alloc] initWithData:data error:&errorInfo];
playerInstance.delegate = self;
if(volume > -1) {
playerInstance.volume = volume;
}
if(currentlyPlaying == nil) {
currentlyPlaying = self;
}
[playerInstance retain];
}
return self;
}
Objective C is new to me, but after looking up some memory management
questions I found this thread :
http://stackoverflow.com/questions/6578/understanding-reference-counting-with-co
coa-and-objective-c and cross referencing apple's doc on memory management (
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgm
t/Articles/MemoryMgmt.html ) ,
it shows that using "retain" bumps up the reference count for an object. So in
this case, the explicit retain on “playerInstance”sets the memory
reference count to initially to 2, so when It is released, it only decrements
to 1 and is kept open by what ever is tracking reference counts in the app.
I do not understand why the retain is there in the first place, and I believe
this is the source of the bug.
Do note that retain is called in both constructors of AudioPlayer (url and
data) so I assume it is a bug in both.
I have run with the retain line commented out in the constructor and it appears
to not resource leak.
Please let me know whether or not you agree with this analysis and if so, let
me know when it will be fixed.
Thanks.
Original comment by killerbe...@gmail.com
on 7 Nov 2013 at 7:08
Also, though I am not using video, I would think the same applies for
[avPlayerInstance retain];
Original comment by killerbe...@gmail.com
on 7 Nov 2013 at 7:21
Thanks, I've committed a fix for this. We had a crash in that class in the past
and just added retains when trying to figure stuff out.
Original comment by shai.almog
on 9 Nov 2013 at 8:34
Original issue reported on code.google.com by
killerbe...@gmail.com
on 22 Oct 2013 at 11:35Attachments: