Should I set object to nill in Swift - ios

I am reading someone's code. He set AVAudioPlayer to nil after user clicking a button to stop the audio from playing. I am wondering should we set object to nil after we don't need it anymore? Or should we set AVAudioPlayer to nil after we are trying to stop playing the audio?

Usually, this is not needed but there are exceptions. When you have a local variable, you almost never need to set it to nil because when it goes out of scope, it will be destroyed anyway.
When you have a variable on instance scope (a property), it's more difficult because you often want to release the memory while the instance is still being used (for example, a property in a controller). In this case, setting to nil is completely correct because you have no other way to remove the object from memory.
The fact that it's a AVAudioPlayer instance shouldn't be relevant although the player usually takes a big chunk of memory so it's good to watch for its instances.

If you have a strong member variable, you may be able to free a significant amount of resources earlier on by deliberately disposing of objects by setting them to nil when no longer required. The benefit will depend on the specific type of object in question.

Related

Are objects immediately released when a property is allocated a second time?

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
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.
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?.

iOS: Moving instance of AVAudioPlayer from one variable to another

Here's what I'm looking to do: I have an AVAudioPlayer called primaryPlayer playing a track, and I want it to continue uninterrupted while I transfer the player to secondaryPlayer. I'll then be using the primaryPlayer for a new AVAudioPlayer instance to play alongside the original track.
Maybe it's as simple as this:
secondaryPlayer=primaryPlayer;
primaryPlayer=[[AVAudioPlayer alloc] initWithContentsOfURL:songURL error:nil];
*these two variables are properties of the class, hence their lack of definition.
I'm worried that I may be missing something. For instance, does this code just set the two variables to point to the same memory address? So that after the second line of code, both variables correspond to the same player?
I think this may be more of an Objective C (or maybe just C) question than anything else, but thanks for reading and any "pointers" on this would be terrific! :)
Assuming that primaryPlayer player points to a valid AVAudioPlayer instance at address 0x1234 and secondaryPlayer has an arbitrary value and that both are declared as strong properties.
secondaryPlayer=primaryPlayer;
Now both variables point to the same object (at address 0x1234).
primaryPlayer=[[AVAudioPlayer alloc] initWithContentsOfURL:songURL error:nil];
secondary player still points to the same object and being a strong reference, that object is still alive. primaryPlayer now points to the newly created object, so now you have two different player objects.

Clean JavaFX property listeners and bindings (memory leaks)

I haven't found a simple answer for these two questions:
do I have to remove a listener before deleting the property instance (the listener is not used anywhere else)?
BooleanProperty bool = new SimpleBooleanProperty();
bool.addListener(myListener);
bool.removeListener(myListener); // is it necessary to do this?
bool = null;
do I have to unbind a uni-directional bounded property before deleting the property instance?
BooleanProperty bool = new SimpleBooleanProperty();
bool.bind(otherBool);
bool.unbind(); // is it necessary to do this?
bool = null;
Case 1
Given that myListener "is not used anywhere else" and therefore I assume, a [method-] local variable, the answer is no. In the general case though, the answer is mostly a no but can sometimes be a yes.
As long as myListener is strongly reachable, then it will never become eligible for finalization and it will continue to consume memory. For example, this would be the case if myListener is a "normally" declared static variable (*all "normal" references in Java are strong references*). However, if myListener is a local variable, then the object will not be reachable anymore after the return of the current method call and bool.removeListener(myListener) is a bit meaningless over-engineering. Both the observer and the Observable goes out of scope and will eventually be finalized. A quote from my own blog post about this answer might paint a better picture:
It doesn’t matter if the box know about the cat inside of it, if you
throw the box into the ocean. If the box isn't reachable, nor is the
cat.
Theory
To fully understand the situation here, we have to remind ourselves of the life-cycle of a Java object (source):
An object is strongly reachable if it can be reached by some thread
without traversing any reference objects. A newly-created object is
strongly reachable by the thread that created it. [..] An object is
weakly reachable if it is [not] strongly [..] reachable but can be
reached by traversing a weak reference. When the weak references to a
weakly-reachable object are cleared, the object becomes eligible for
finalization.
In the case of static variables, these will always be accessible as long as the class is loaded, thus reachable. If we didn't want a static reference to be the one that hinder the garbage collector to do his job, then we could declare the variable to use a WeakReference instead. JavaDoc says:
Weak reference objects [..] do not prevent their referents from being
made finalizable, finalized, and then reclaimed. [..] Suppose that the
garbage collector determines at a certain point in time that an object
is weakly reachable. At that time it will atomically clear all weak
references to that object [..]. At the same time it will declare all
of the formerly weakly-reachable objects to be finalizable.
Explicit management
For illustration, let's assume that we write a JavaFX space simulation game. Whenever an Observable planet moves into the view of a spaceship observer, the game engine register the spaceship with the planet. It is quite apparent that whenever the planet goes out of view, the game engine should also remove the spaceship as an observer of the planet by using Observable.removeListener(). Otherwise, as the spaceship continues to fly through space, memory will leak. Eventually, the game cannot handle five billion observed planets and it will crash with an OutOfMemoryError.
Do note that for the vast majority of JavaFX listeners and event handlers, their life-cycle is parallel to that of their Observable so the application developer has nothing to worry about. For example, we might construct a TextField and register with the text field's textProperty a listener that validate user input. As long as the text field sticks around, we want the listener to stick around. Sooner or later, the text field is not used anymore and when he is garbage collected, the validation listener is also garbage collected.
Automatic management
To continue on the space simulation example, assume that our game has limited multiplayer support and all the players need to observe each other. Perhaps each player keep a local score board of kill metrics or perhaps they need to observe broadcasted chat messages. The reason is not the important point here. What would happen when a player quit the game? Clearly, if the listeners are not explicitly managed (removed), then the player who quit will not become eligible for finalization. The other player's will keep a strong reference to the offline player. Explicit removal of the listeners would still be a valid option and probably the most preferred choice for our game, but let's say that it feels a bit obtrusive and we want to find a more slick solution.
We know that the game engine keep strong references to all players online, for as long as they are online. So we want the spaceships to listen for changes or events of each other only for as long as the game engine keep the strong references. If you read the "theory" section, then surely a WeakReference sounds like a solution.
However, just wrapping something in a WeakReference is not the entire solution. It seldom is. It is true that when the last strong reference to the "referent" is set to null or otherwise become unreachable, the referent will be eligible for garbage collection (assuming that the referent cannot be reached using a SoftReference). But the WeakReference is still hanging around. The application developer need to add some plumbing so that the WeakReference itself is removed from the data structure he was put in. If not, then we might have reduced the severity of the memory leak but a memory leak will still be present because dynamically added weak references consume memory too.
Lucky for us, JavaFX added interface WeakListener and class WeakEventHandler as a mechanism for "automatic removal". The constructors of all related classes accept the real listener/handler as provided by client code, but they store the listener/handler using a weak reference.
If you look at the JavaDoc of WeakEventHandler, you'll notice that the class implement EventHandler, so the WeakEventHandler can be used wherever an EventHandler is expected. Likewise, a known implementation of a WeakListener can be used wherever an InvalidationListener or a ChangeListener is expected.
If you look into the source code of WeakEventHandler, you'll notice that the class is basically only a wrapper. When his referent (the real event handler) is garbage collected, the WeakEventHandler "stop working" by not doing anything at all when WeakEventHandler.handle() is called. The WeakEventHandler doesn't know about which object he has been hooked up with, and even if he did, the removal of an event handler is not homogeneous. All known implementing classes of WeakListener has a competitive advantage though. When their callbacks are invoked, they are implicitly or explicitly provided a reference to the Observable they are registered with. So when the referent of a WeakListener is garbage collected, eventually the WeakListener implementation will make sure that the WeakListener itself is removed from the Observable.
If it is isn't already clear, the solution for our space simulation game would be to let the game engine use strong references to all online spaceships. When a spaceship goes online, all other online spaceships are registered with the new player using a weak listener such as WeakInvalidationListener. When a player goes offline, the game engine remove his strong reference to the player and the player will become eligible for garbage collection. The game engine doesn't have to bother about explicit removal of the offline player as a listener of the other players.
Case 2
No. To better understand what I'll say next, please read my case 1 answer first.
BooleanPropertyBase store a strong reference to otherBool. This in itself does not cause otherBool to always be reachable and thus potentially cause a memory leak. When bool becomes unreachable, then so do all its stored references (assuming they are not stored anywhere else).
BooleanPropertyBase also works by adding itself as an Observer of the property you bind it to. However, it does so by wrapping itself in a class that works almost exactly like the WeakListeners described in my case 1 answer. So once you nullify bool, it will be only a matter of time before it is removed from otherBool.
I completely agree with the case 1 answer, but the case 2 is a bit more tricky. The bool.unbind() call is necessary. If ommitted, it does cause a small memory leak.
If you run the following loop, the application will eventually run out of memory.
BooleanProperty p1 = new SimpleBooleanProperty();
while(true) {
BooleanProperty p2 = new SimpleBooleanProperty();
p2.bind(p1)
}
The BooleanPropertyBase, intenally, does not use a real WeakListener (an implementation of the WeakListener interface), it is using a half-baked solution. All the "p2" instances get eventually garbage-collected, but a listener holding an empty WeakReference remains in the memory forever for each "p2". The same holds for all properties, not only BooleanPropertyBase. It's explained here in detail, and they say it is fixed in Java 9.
In most cases, you do not notice this memory leak, because it leaves only a few dozen bytes for every binding that has not been unbound. But in some cases it caused me real trouble. An good example are table cells of a table that gets frequently updated. The cells then re-bind to different properties all the time, and these left-overs in the memory accumulate quickly.

Hang on SomeObject.Free. Check if object is already free in FPC?

if if have an object (in my case TJSONData) and I want to free this object the programm flow sometimes hangs at this position. I already have a construct like the following in my code but it seems to not fit the case some times:
if Assigned(MyRecord.MyJSONData) then
begin
MyRecord.MyJSONData.Free;
end;
I can reproduce this behavior in tests if I try to free an object two times. In my program this should normally not happen but now my real question:
Is there a way to check if the object is already free? Or do I need to use also FreeAndNil();?
The Assigned function checks to see if a reference is not nil. It
returns True if not nil, and False if nil.
Obviously when you free the object and do not set reference to nil it will pass on next Assigned check (reference <> nil) and will be attempted to free again. But the reference (pointer) is already dangling (pointing to freed or worse, changed, memory).
Generally you should set your references to nil or better - use FreeAndNil function. This way each time you will want to access the freed object it will be nil and thats your check.
There was a large thread in Delphi forum (the tread that eventually crushed the forum) about FreeAndNil.
Common point was that for 95% of tasks you should not check if an object is alive, you should know it beforehand and architect the program so that you always know and never need those checks.
Some survived or revived links are at http://www.theregister.co.uk/2012/01/16/verity_stob_sons_of_khan_2011/print.html and at https://forums.embarcadero.com/message.jspa?messageID=413796

ARC in iOS questions

~ Will ARC always release an object the line after the last strong pointer is removed? Or is it undetermined and at some unspecified point in the future it will be released? Similarly, assuming that you don't change anything with your program, will ARC always be the same each time you run and compile your program?
~ How do you deal with handing an object off to other classes? For example, suppose we are creating a Cake object in a Bakery class. This process would probably take a long time and involve many different methods, so it may be reasonable for us to put the cake in a strong property. Now suppose we want to hand this cake object off to a customer. The customer would also probably want to have a strong pointer to it. Is this ok? Having two classes with strong pointers to the same object? Or should we nil out the Bakery's pointer as soon as we hand off?
Your code should be structured so the answer to this doesn't matter - if you want to use an object, keep a pointer to it, don't rely on ARC side effects to keep it around :) And these side effects might change with different compilers.
Two strong pointers is absolutely fine. ARC will only release the object when both pointers are pointing to something else (or nothing!)
ARC will implement the proper retains and releases at compile time. It will not behave any different than if you put them in there yourself so it will always do the same compilation and to answer your question should always behave the same. But that said it does not mean that your object will always be released immediately after the pointer is removed. Because you never call dealloc directly in any form of objective C you are only telling it that there is no reference count and that it is safe to release. This usually means that it will be released right away though.
If you pass an object from one class to another and the receiving class has a strong property associated with it and the class that passes it off eventually nils its pointer it will still have a reference count of at least 1 and will be fine.
Ok, first this answer might helpt you also a little bit: ARC equivalent of autorelease?
Generally after the last strong variable is nilled, the object is released immediately. If you store it in a property, you can nil the property, assign it to something like __strong Foo *temp = self.bar; before you nil, and return that local __strong variable (although arc normally detects the return, and inferes the __strong byitself).
Some more details on that: Handling Pointer-to-Pointer Ownership Issues in ARC
DeanWombourne's answer is correct; but to add to (1).
In particular, the compiler may significantly re-order statements as a part of optimization. While method calls will always occur in the order written in code (because any method call may have side effects), any atomic expression may be re-ordered by the compiler as long as that re-order doesn't impact behavior. Same thing goes for local variable re-use, etc...
Thus, the ARC compiler will guarantee that a pointer is valid for as long as it is needed, no more. But there is no guarantee when the pointed to object might be released other than that it isn't going to happen beyond the scope of declaration. There is also no guarantee that object A is released before B simply because A is declared and last used before B.
IN other words, as long as you write your code without relying on side effects and race conditions, it should all just work.
Please keep you code proper as it has diffrent behaviour on diffrent complier.

Resources