One way to declare and assign the notification name is using global strings in .h file:
then assigning the values in the .m file:
However, long strings like this are hard to scan when reviewing the code. Thus I prefer to namespace them using structs. In the .h file:
1 2 3 4 5 6 7
then setting up properties in the .m file:
1 2 3 4 5 6
Attach in init, detach in dealloc
Always assign yourself as observer in the
init method, not in
viewDidLoad. That way, you can cover cases where your controller is in memory but its view is not - like when it’s a member of
UITabBarController.viewControllers but it’s not yet shown.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Since iOS 9, you don’t need to explicitly call
dealloc - for previous version make sure you do it.
1 2 3 4
Make sure to check is the view actually loaded before trying to update anything related to the view hierarchy.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Notice the form: you pass the notification, when matched in the
if block it ends with
return. This is mandatory, even if you have only one notification. Sooner or later you will add another and missing
return statement may come to hunt you. Don’t trust yourself nor anyone else that it will correctly scan and scrutinize already existing code in
Treat each notification like it’s a world of its own - never write any code outside the
if block for particular notification. It will save your sanity a year in the future.
In the same vein, wrap entire UI processing in the notification inside
dispatch_async call targeting main thread. It does not matter how absolutely positively 100% sure you are that this notification will be posted on the main thread - still wrap its handler inside such block.
If you override loadView…
Additionally, if you have your own
loadView that does something, then you need to track when has that method completed and only then is your
self.view really loaded. If you ignore this problem, you may end up with some really confusing crash logs.
For example: if you add UICollectionView as subview in the loadView method and you set
.dataSource in that place as well. So, now imagine a notification that fires up CV’s
reloadData - with enough customers using your app you’re bound to have at least few customers getting into that line in the nano/microsecond between the
[super loadView] and the
addSubview call in your override.
To safeguard your code, add local property like this one:
set it to
NO in the
init method and set it to
YES as the very last line of your
loadView method. Then override
isViewLoaded to account for this change:
1 2 3 4 5
Needless to say - none of the stuff you do in your
loadView method should consult
Or you can take the high road and don’t assign delegates and dataSources in
loadView (do it in
viewDidLoad). But then again – copy-paste programming has so much allure and developers love shortcuts…