Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xcode now generates an empty category. Why?

I noticed this while using iOS6 beta 3

When I create a new subclass of a UIViewContoller (no other parent classes generate this behavior that I've noticed), the .m file now has an empty category at the top of the file. In the past when learning about categories I noticed that some people would use this same technique to indicate private methods (although not truly private).

Is that what the intent is here? Has there been any change to making things actually private now? I notice the @private directive out there too.

What is your person coding style regarding private vars and methods?

UPDATE: Since XCode is pushing us to use the class extensions, I went ahead and used them for private methods/ivar for this project. I found a drawback though. I saw that I could reuse one of my subclassed UIViewControllers along with all of it's UIButtons, UILabels, etc.... I had this inheritance: UIViewController <- FirstViewController <- SecondViewController.

Well, all of the private methods that I put in the class extension of FirstViewController do not pop up in the autocomplete when I code in SecondViewController. A slight annoyance....

like image 777
VaporwareWolf Avatar asked Jul 27 '12 00:07

VaporwareWolf


1 Answers

You're referring to this interface definition:

@interface MYViewController ()
@end

This is technically a class extension rather than a category. Categories have a string inside the parentheses. Class extensions are added to the class at compile time, and so can add ivars (usually in the form of properties). Categories are added at runtime and cannot add ivars.

All that said, your point is correct. This is used to define private methods and properties.

In the ObjC world, "private" is a "no trespassing" sign, not a razor-wire wall. While there is a @private keyword (that adds compiler enforcement), it only applies to ivars, and generally isn't necessary. This type of warning-based privacy works very well in ObjC and is quite sufficient.

Put your private properties in this class extension, and outside callers will get "may not respond to selector" warnings if they try to access them (just like they would get for calling any undefined method). You should never allow warnings to exist in an ObjC project, so this enforces data encapsulation.


EDIT

If they're private, then they shouldn't pop up in your subclass. What you want is protected. There's no great scheme for protected methods in ObjC, but a common technique is to put them into a category in a .h file like MYViewController+Protected.h. I find this comes up very seldom in practice, since so much of good ObjC design doesn't subclass. It uses composition and delegation instead.

Regarding "Why just view controllers." First, it's not just view controllers. It's just view controllers on iOS (well, VC, TableViewController, and GLKViewController). On Mac, it's also window controllers and spotlight importers. Look in:

.../Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates
.../Library/Xcode/Templates

But why those? Well, those are all controllers, and it's insanely common for controllers to need private properties. In fact, if you don't have private properties in a controller, you're probably making too much public. That's not as universal of model and view classes. I suspect that played into their decision. It might also have been different people who owned the templates, or that they were updated at different times. Sometimes you see little inconsistencies that smooth out over time.

You can make your own templates as well. See Creating Custom Xcode 4 File Templates.

like image 148
Rob Napier Avatar answered Oct 04 '22 22:10

Rob Napier