0

I am working on an app where I am presenting 100 sentences using AVAudioplayer. Rather than have 100 AVAudioplayer objects I wanted to just have one property and change the object associated with it on the fly. My code boils down to the following (though the lines arent immediately following each other in the actual code):

self.thePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url1 error:&error]; 
self.thePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url2 error:&error]; 

Does the object initialized with url1 get released when thePlayer is allocated and initialized a second time with url2, or are both objects only released when the view is dismissed? As I am dealing with 100 sound files I don't want them all hanging around in memory. I'm using ARC

Thanks in advance

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • The object created using url2 (let's say second object for convenience), and the object which was created using url1 (let's say first object for convenience).When you set the thePlayer property to the first object it's reference count will be one and when you set the thePlayer property to refer to the second object, the second object's reference count will be incremented and becomes one from zero.Now when you reset the property to refer to second object, the first object's reference count will be zero, and the objects whose ref count is 0,will be destroyed unless there are no strong ref to it. – iamyogish Dec 06 '15 at 15:47

2 Answers2

1

In your specific case, guessing at what your code likely includes, the objects will probably be deallocated when you want them to be. That's a lot of "guessing," "likely," and "probably." You really need to understand how the memory management works in order to reason about it.

If the AVAudioPlayer is strongly referenced by anything else, then it won't be released until those strong references are gone. In other words, setting thePlayer won't deallocate the player if something else has a strong reference to it. (That "something" may be some part of the system frameworks, or even itself in some rare cases. It doesn't have to be your code.)

If the AVAudioPlayer has pending autorelease calls on it, then it won't be released until the autorelease pool drains (usually at the end of event loop, which basically means "when your method that UIKit called returns.") For example, if you create a large number of objects in a loop and immediately throw them away, they may or may not be deallocated until the autorelease pool drains. Again, autoreleases may be injected by system frameworks. In practice, this means that the object will usually be deallocated "soon" (in a small fraction of a second), but not necessarily immediately. You can clean up autoreleased objects sooner by using @autoreleasepool blocks, which is sometimes necessary if you create many temporary objects in a loop. This is not needed very often.

But to a first-order approximation, in many of the most common cases, yes, replacing the property will automatically and immediately deallocate the previous object.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
0

It would be useful to show how you declared thePlayer. If they are synthesized properly the memory management would be handled automatically. It appears that you are using "self" to access thePlayer and if so you'd be setting the value through a setter/getter and that would handle the memory management for you. But I also notice that "Self" is capitalized and should not be in order to properly use the setter/getter. For more info on synthesized variables check out: What exactly does @synthesize do?. Note there are some places where you should NOT use self and this link discusses that: How does an underscore in front of a variable in a cocoa objective-c class work?.

Community
  • 1
  • 1
xdeleon
  • 769
  • 8
  • 20
  • I typed the question up on my iPad and it auto capitalized the self. It's not capitalized in the code. Thanks for the links, will check them out – henrytyper Dec 06 '15 at 16:46