What kind of property should be set to nil in dealloc? - objective-c

I'm using ARC. Will ARC automatically release all the properties in dealloc? Is it necessary to manual set all public properties and private field to nil? Are there any good pattern to follow?

Under ARC, the pattern is... don't do anything in dealloc, or even implement it. ARC takes care of your properties and instance variables for you.
The only exception is that dealloc is a good place to unregister for notifications, if your object has registered for any.

Good question. When using ARC the compiler will implement a dealloc method for you and will handle implicitly the release of your instance variables and properties.
You may still need a custom -dealloc if your class needs to do anything other than releasing memory (e.g unregister for notifications like jrturton mentioned).
You can get a good grasp of what's you need to consider when transitioning to ARC in those Apple official notes.

Related

Do observers need to be removed in Swift 4/Objective-C?

I'm trying to implement KVC/KVO in Swift 4. Much of the documentation I've read up on for KVC/KVO in Objective-C states that the observer needs to be removed when you are done with it. But, after looking at Apple's documentation of the implementation of KVO using Swift 4, they don't explicitly state whether or not the observer needs to be removed in a deinit method. They do not include a deinit method in the example class definition. But, I do not want to make any assumptions since all the Objective-C documentation I've read states that the observer needs to be removed.
https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html#//apple_ref/doc/uid/TP40014216-CH7-ID12
I'm just not sure whether or not the observer needs to be removed through a deinit. Any help or point in the direction of a reference would be great, thanks.
If you are talking about NSKeyValueObservation: No they don't.
From the transcript of the WWDC 2017 Video "What is new in Foundation"
There is no need for a deinit where I throw away or tear down my observation because it's tied to the life cycle of that observation token. And so when the controller goes away, the observation token will go away.
The rules around deregistering observers was relaxed in 10.13, from the Foundation Release Notes (emphasis added):
Relaxed Key-Value Observing Unregistration Requirements
Prior to 10.13, KVO would throw an exception if any observers were still registered after an autonotifying object's -dealloc finished running. Additionally, if all observers were removed, but some were removed from another thread during dealloc, the exception would incorrectly still be thrown. This requirement has been relaxed in 10.13, subject to two conditions:
The object must be using KVO autonotifying, rather than manually calling -will and -didChangeValueForKey: (i.e. it should not return NO from +automaticallyNotifiesObserversForKey:)
The object must not override the (private) accessors for internal KVO state
If all of these are true, any remaining observers after -dealloc returns will be cleaned up by KVO; this is also somewhat more efficient than repeatedly calling -removeObserver methods.
HTH

Override "release" or "dealloc"

Which is the best method
Override "release" or "dealloc" method in objective c?
why?
Under non-ARC, 99% of the cases you should not override the release method.
I have seen only 1 case that the need to override the release method - a kind of singleton, which forces the class have really 1 single instance no matter how many times you call alloc.
That way override not only the release method, but also allowWithZone:, retain, 'retainCount`, etc. (It is actually not common to implement that kind of singleton)
Which is the best method? Override the release or the dealloc method?
- dealloc, definitely. You should never override - release.
Why?
One, because release does a bunch of internal stuff. Two, because if release is called, it does not mean that the object is deallocated.
So you would release your ivars or null your properties by accident. And who wants an ugly segfault when we can have worldpeace instead?
If an object is really deallocated, - dealloc will be called.
If you are not using ARC, you should override the -[MyObject dealloc] dealloc method to release all retained objects inside your object. I have never found a case where I needed to override the release method.
If you are using ARC, you can usually avoid overriding the -dealloc method at all, unless you are using anything that ARC won't free up like a sqlite pointer or something.
dont override either for anything not relating to memory management - you dont when and if those methods even get called.
exceptions for when you should dealloc:
removing KVO / notification center observer
deallocating manually allocated memory (arc) / release your ivars (non-arc)

Should I release instance variables and properties in dealloc?

According to Apple's documentation on the View Controller Lifecycle I noticed the following regarding the dealloc method:
Override this method only to perform any last-minute cleanup of your
view controller class. Objects stored in instance variables and
properties are automatically released; you do not need to release them
explicitly.
I've been taught always to call release on instance variables and properties that I own in my view controller's dealloc method.
The only exception I was aware of is when using ARC but it does not mention ARC in this documentation.
Is this correct?
Since the guide you posted was updated recently, I'm pretty sure that it assumes you're using ARC (you should do that, after all, if possible).
You're correct, before ARC, you had to release your instance variables in the dealloc method (you can see that in the old XCode templates in the dealloc of the App-Delegate). With ARC, this gets handled automatically (as this guide says), so except for special needs, the dealloc method is not used anymore.
As JiaYow mentions, that guide has been updated to ARC. Here you can find the Legacy guide for view controllers: https://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewControllerPGforiOSLegacy/BasicViewControllers/BasicViewControllers.html#//apple_ref/doc/uid/TP40011381-CH101-SW1

iOS: Retaining a shared instance

I am using a shared instance of a singleton class in a function, do I need to do a retain on the object? A few examples I have seen do this: AVAudioSession *session = [[ AVAudioSession sharedInstance] retain]; while a few simply do: AVAudioSession *session = [ AVAudioSession sharedInstance];. I am sure there is a rule somewhere which should tell me what to do but I just don't know it.
Simply treat it as if it were any other object. Sometimes a singleton class will override memory management methods to ensure that it doesn't get deallocated, but there is no way to know whether or not a shared object has this. With shared objects and singletons which don't, if the first gets deallocated a new one will be created as needed. Therefore, if you need to ensure that a pointer is valid in a future method, retain the shared object when you get it. If you don't need to keep it, you don't need to do anything as the sharedInstance method will autorelease it.
You're right, there are rules that tell you what to do. They're the same rules you use everywhere else in Cocoa Touch. Clients of a singleton shouldn't care that the object they're using is a singleton, and they definitely shouldn't rely on the singleton's single-ness to avoid the usual memory management conventions.
Yes, if you know that an object is a singleton and you know that it won't be deallocated, retaining it might seem redundant. On the other hand, retaining the singleton when you acquire it and releasing it when you're done better documents the programmer's intent and avoids the need to explain to anyone (including the future you) why it's okay not to retain this particular object. Most importantly, it prevents your code from depending on an implementation detail of some other part of your code.
you do'nt need to retain the sharedInstances because it's implemented as the singleton class.

Objective-C Delegate Pointers

If we write the following code:
ExplorerAppDelegate * appDelegate = (ExplorerAppDelegate *)[[UIApplication sharedApplication] delegate];
This makes a reference to the original delegate pointer, but:
Does it increase the reference count?
Do we have to explicitly call as [ExplorerAppDelegate retain] right after, or not at all?
What's happening, exactly?
After we've used this, we should also do a [ExplorerAppDelegate release] in the dealloc method, right?
No, it does not increase the retain count.
The convention in Objective-C is that objects you are given should be memory managed by yourself - but in the case of obtaining a shared common resource like the app delegate, the memory is maintained elsewhere and of course (with this being the app delegate) you know that it will always be "alive" as long as your class is... so there is no need to retain the reference.
In most uses of delegates, instead of fetching a delegate you are given one, and that reference is not retained either. In that case whoever gave you the delegate is also responsive for clearing out the delegate link before the delegate is released.
The reason you don't want to generally retain delegate references is that it can prevent some objects from being deallocated, for instance if one class is a delegate of a class that ues the other class as a delegate.
The reference count will not be increased
You should retain it if you want to be sure that it isn't deallocated while you have a pointer to it
You should only release it if you retained it
So basically, if you're only using the object in a single function, you probably don't need retain or release it. If it exists when you get it, then it's (probably) not going to be deallocated by the end of the function. If you're keeping it around, in an ivar (member variable) for example, then you should retain it and release it later.
See the "Weak References to Objects" in Memory Management Programming Guide for Cocoa for the official answer. Pointers to delegates are one of the possible exception cases to the memory management rules.