What is the purpose of a class extension without any content? - objective-c

According to developer documentation, a class extension is implemented by declaring an #interface in the implementation file, and it can also be used to redeclare instance variables to be private. However, I frequently see the code below that does not declare new methods or instance variables. What is its purpose?
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
...

There is no purpose behind such code. The only reason it is there is that it is part of the standard template for creating .m files in Xcode.
With this said, such class extensions are entirely harmless, so keeping them in case you need to add private methods or variables does not hurt performance of your app. In the end, it is a matter of personal taste: for example, I remove such unused template-generated artifacts from my code, but I can accept an argument in favor of keeping them as well.
If you do not wish to have these class extensions generated by default, clone and modify Xcode template for new Objective-C classes (here is a Q&A explaining how to do it).

Related

Objective-C #interface and #implementation clarification

I'm still fairly new to Objective-C but I'd love to learn more about how it should be done.
I'm building a simple cheat sheet that I'd like to print and put on my office wall as a reminder.
Here's what I have so far:
// Headers (.h)
// Shows what's available to other classes
#interface ExampleViewController : UIViewController
// Declare public methods, ivars &
// properties that are synthesized.
#end
// Implementation (.m)
// Defines the content of the class
#interface ExampleViewController ()
// Class extension allowing to declare
// private methods, ivars & properties that are synthesized.
#end
#implementation ExampleViewController
// Private Properties
// Method definitions
#end
One thing I don't understand is why have both #interface and #implementation inside the implementation .m file?
I get that we can declare private stuff but why not simply throw them in #implementation like:
#implementation ExampleViewController
UIView *view; // private property
- (void)...more code
#end
#1 - Why should I ever use #interface from within my implementation .m file?
#2 - For header .h, why should I ever use #class more than #import?
#import actually gets the whole definition and #class tells the compiler that the symbol is a class. So I just don't see why I should ever use #class?
#3 - Otherwise, is there anything I should be adding somewhere in my .h or .m cheat sheet?
That's not a problem-related question but a more wiki-esque question so we everybody can look it up and completely and quickly understand those concepts as they are very hard to grasp for any newcomer.
Why should I ever use #interface from within my implementation .m file?
Because it's better to clearly separate public and private parts of the class.
For header .h, why should I ever use #class more than #import?
When forward-declaring classes for use in protocols. Like this:
#class Foo;
#protocol FooDelegate
// this wouldn't compile without a forward declaration of `Foo'
- (void)fooDidFinishAction:(Foo *)f;
#end
Otherwise, is there anything I should be adding somewhere in my .h or .m cheat sheet?
That's way too general to be answered in one post.
1 - Why should I ever use #interface from within my implementation .m file?
When you do not intend to expose that interface to any other component. That's certainly the case for private class extensions but may also apply for something like a test which doesn't need a .h file at all because while it does define a class it does not need to expose an interface for any other component to use.
2 - For header .h, why should I ever use #class more than #import?
Invert your question; why should I ever use #import rather than #class?
#class informs the compiler that a class definition of that name will exist to be linked but says nothing about it's interface.
#import makes the class' interface available to you.
A forward declaration requires less work and can allow for faster builds. It is also not always possible to #import a class at all times (as in circular references like #H2CO3's protocol example). If all you need to know is that a class exists then just use the forward declaration. When you actually need to interact with its specific interface (usually in your class' implementation) then you need to #import.
3 - Otherwise, is there anything I should be adding somewhere in my .h or .m cheat sheet?
Unless you intend to actually expose ivars as a public interface (almost certainly not the case) leave them out of your .h and expose only properties instead.
Keep your public interface as simple as possible. Try not to reveal implementation details. However keep it informative enough that users of the class can verify its behavior using that public interface. (I find test driving the design of the class using only it's public interface a good tool for striking this balance.)
Imports and forward declarations expose dependencies. Keep them to the minimum you actually need so that you can understand what the class in question actually depends on.
Delegate protocols and block types are a common part of a class' interface but not part of the #interface. Include them in the .h if they are needed by other classes (e.g. to register callbacks).

When do you create initialization methods in .m files using class extension?

I was going through one of Apple's tutorial (your second iOS app). Basically, you have a primary data class and a data controller class. Controller class manipulates the primary data objects by creating an array that holds them.
Suddenly this pops up:
"...But the “create the master collection” task is a task that only the data controller object needs to know about. Because this method does not need to be exposed to other objects, you do not need to declare it in the header file."
And turns out the initialization of the "master collection" appears in the .m file as a class extension instead of the header file. Why do we want to do this? What's wrong with declaring the method of initialization within the header file directly?
Header file of the data controller:
#import <Foundation/Foundation.h>
#class BirdSighting;
#interface BirdsSightingDataController : NSObject
#property (nonatomic, copy) NSMutableArray *masterBirdSightingList;
- (NSUInteger)countOfList;
- (BirdSighting *)objectInListAtIndex:(NSUInteger)theIndex;
- (void)addBirdSightingWithName:(NSString *)inputBirdName location:(NSString *)inputLocation;
#end
this is the corresponding .m file:
#import "BirdsSightingDataController.h"
#import "BirdSighting.h"
#interface BirdsSightingDataController ()
- (void)initializeDefaultDataList; //class extension
#end
#implementation BirdsSightingDataController
...
Putting methods in an interface inside of a .m file is the proper way of making methods hidden.
-
There's nothing really "wrong" with declaring this method in the header file. You can do this if you want.
However, it's better practice to hide methods in your implementation file by using private header extensions if there's no need to make the method public. This means that if no other class needs to call this method, or if no other programmer needs to call this method, then it's better practice to keep the method private, or hidden.
A case like this will help explain the situation:
First, putting methods in a hidden interface extension in your .m files is a conscious decision. As another developer, if I am looking at your code and see that you have consciously decided to put a method in a hidden interface () in your implementation file, I will know that this method is used only in this class... and that YOU have done this on purpose.
Furthermore, it is good practice because if you are developing an API which is going to be used by other people, or working on the same code base with other developers, it limits their ability to call specific methods outside of the class itself. That means, they can't accidentally call the method from another object.

Purpose of Obj-c categories in a specific situation.

I'm quite new at Objective-C and i've a question :
I've been through some Apple's sample code and found the following :
https://developer.apple.com/library/ios/#samplecode/GLSprite/Listings/Classes_EAGLView_m.html#//apple_ref/doc/uid/DTS40007325-Classes_EAGLView_m-DontLinkElementID_4
In the top of the file, I found to uses of Objective-C categories
#interface EAGLView (EAGLViewPrivate)
- (BOOL)createFramebuffer;
- (void)destroyFramebuffer;
#end
#interface EAGLView (EAGLViewSprite)
- (void)setupView;
#end
Just after that, starts the implementation of the EAGLView class.
What is the real purpose of categories here, as the 3 functions above could also be defined directly in the header file ??
Thx
As indicated by the first category's name ("EAGLViewPrivate") declaring these methods in the .m file is a way of simulating private methods. Objective-C doesn't have true support for private methods, but since these aren't declared in the .h file, the compiler will warn when code outside the .m file where they're declared tries to call them.
This is more commonly done with class extensions (a special case of a category) these days, mostly because using a class extension results in the compiler warning if a "private" method isn't implemented in the class's #implementation block. Class extensions were a new feature in Objective-C 2.0, so in older code, you'd often see a category with private in the name as in the code you've posted. The intent is the same.

What is the empty #interface declaration in .m files used for?

I've started a new iOS 5 project and noticed something new at the top of each .m file
#import "HomeViewController.h"
#interface HomeViewController ()
#end
#implementation HomeViewController
#synthesize ...
Is this extra #interface ... required if I have a separate .h file?
Why did this not show up in pre iOS 5 projects?
Can I use this instead of having a separate .h file?
What is the best practice for this going forward?
That's a class extension. You can use it to make declarations that you don't want to be in the .h file.
This was used by many developers, even before, who manually added the extension in the .m file. So I guess Apple included this in the template because it is widely used and is considered a good practice.
In fact, the .h file should only be used to make declarations that are going to be used from other files. You may have to declare some properties, methods or constants that will only be used inside the .m file. For those declarations, it is better to make them in the class extension.
So to answer your questions:
Is this extra #interface ... required if I have a separate .h file?
No, it is not required but is a best practice.
Why did this not show up in pre iOS 5 projects?
Even if this was a commonly used practice, it was not included in the template.
Can I use this instead of having a separate .h file?
No. The class extension doesn't replace the .h file where you have to declare the "public" interface of your class.
What is the best practice for this going forward?
You should put in the class extension all the declarations that don't need to be visible outside of the .m file.
The interface section in the implementation file allows you to declare variables, properties, and methods that are private, meaning that they won't be seen by other classes.
No, it's not required at all. But I use it as much as possible and only make public those things that other classes need to see.

When & why do you use #interface ClassName (Private)? - Objective-C

I was looking at some code:
#interface ClassName (Private)
- (float)methodOne:(NSDictionary *)argOne;
- (void)methodTwo:(NSDictionary *)argTwo;
#end
#implementation ClassName
....
The above code is at the top of the ClassName.m file which appears to define additional interface methods for the class as private?
Why do this? what is the point? What else could go where (Private) is? Anyone have docs on this?
Thanks
This is a way of keeping methods that the class uses internally from being exposed to others. It's part of encapsulation. In Objective-C 2.0 (iOS and Mac OS X 10.5+), it's more common to use a class extension at the top of the implementation file:
#interface ClassName ()
- (void)privateMethod;
#end
A class extension is really just a special case of a category (which is what you've asked about). The primary difference is that for a category, the compiler won't complain even if your #implementation doesn't include definitions for the methods declared in the category. For methods in a class extension, your class must implement those methods in its main #implementation block or you'll get a compiler warning.
You're better off using a class extension in iOS code or Mac code that targets at least Mac OS X 10.5 Leopard.
Basically it is a category and allows adding methods in the .m file. These days the best way is to use a Class Extension, the syntax is similar just the "Private" is missing, just two parentheses.
The additional advantage of a class extension is that properties can also be included and the compiler will validate that all methods declared are defined.
One area that is really handy is the ability to declare a properly readonly in the .h file and read write in the .m file. That way users of the class only have read access but the class itself has full access.
The objective-c does not support private method, and the way you are asking is a substitution for that.
you can check this link for detail:
Why doesn't Objective-C support private methods?