Objective-C: Is a class just a .m and .h file? - iphone

I'm still coming to terms with classes and objects in Objective-C.
Is a class simply the combination of an interface and implementation file? Or, to put it another way, when would you say to yourself "I need a new .m file for this". At the moment I make a new implementation file when I want to put certain methods and variables in a separate place so that my main code doesn't become massive.
Any help would be greatly appreciated.

Strictly by convention and not by necessity, every new class should have an interface file (.h file) and an implementation file (.m file).
As far as using new .m files for distributing your methods, this is fine.

While convention dictates a pair of .h and .m files per class, the former containing the #interface and the latter containing the #implementation, there is no such requirement and, in fact, many of the system provided classes are divided across several files both in interface and implementation.
Technically, you don't need an #interface at all.
The absolute minimal class definition is:
#implementation Foo
#end
In that the above defines a class Foo that is a new root class. However, the compiler will warn about this.
Effectively, the minimal class definition is:
#interface Foo:NSObject
#end
#implementation Foo
#end
Note that NSObject is intentional; if you are going to make a class that will be compatible with the system frameworks or, even, the system runtime, inheriting from NSObject is pretty much required.
Syntactically, it is up to you as to how you separate the #interface and the #implementation. Traditionally, the interface goes in a header file such that others might #import it and use it while the implementation goes into a compilation unit -- a .m file -- to be compiled and linked exactly once.
But that is convention, not requirement. I've often defined a class --- #interface + #implementation -- entirely in a single .m file solely for use within the #implementation of some other class; effectively, a private class.
Note that class extensions -- #interface Foo() -- were expressly created to allow you to declare additional properties and methods on a class outside of the .h file's #interface Foo:NSObject. It allows a class to effectively have hidden API or to create a property that is publicly readonly and privately read-write.

No it's not. You can place multiple classes in a .h and .m file, althought this isn't deemed good practice.

In Objective-C classes are a pair of interfaces and implementations. These don't have to be in separate files but often are and it is a good way to keep your file structure clean. Often classes represent a little factory and when you have a group of functions that can be grouped together it is a good idea to put them in a class together.

I'll admit to occasionally grouping a few classes together, either with the definitions of all in one .h and the implementations in one .m, or, where some classes are "private", with the definitions AND implementations of "inner" classes in the .m of the major class.
I think it's sometimes good to avoid a proliferation of files this way, and to group interdependent classes together.
You can also go the other way -- spread the definition and and/or implementation of a class among multiple files using "categories" -- but that's a touch ugly and should generally be reserved for extending frameworks classes with specialized functions. (And even at that, done with some apprehension.)

Related

Declaring a delegate protocol

I would like to know what is the difference when declaring a protocol in the same class and when declaring it in a separate file; example :
#import <UIKit/UIKit.h>
#class MyClassA;
#protocol MyDelegate <NSObject>
#required
- (MyClassA*)myMythod;
#optional
- (void)anOtherMethod:(NSString*)ID;
#end
#interface MyClassB : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, assign) id <MyDelegate> delegate;
......
here I declare the protocol delagate in the same file with MyClassB, and I can declare it (the protocol delegate) in a separate source file. What is the difference between declaring it in the same file with the class and in a separate file? Thanks!
There definitely are subtle differences.
If the protocol you are talking about is a delegate that is used by one particular class, for example, MySpecialViewController, and MySpecialViewControllerDelegate, then you might very well like to keep the declaration of both of those in the same header. If another class is going to implement that protocol, for example, it's probably going to depend logically on the MySpecialViewController class. So, you're not introducing any additional dependencies.
But, there's another significant reason (at least) to use protocols. You might be trying to decouple a bidirectional dependency between two classes. Of course, the compiler doesn't let two headers #import one another. But, even if you move one class's #import to the .m file, it's often a sign of a poor design to have two classes each fully aware of one another's complete API.
One way to decouple this relationship a little is to make one class aware of the other only through a protocol that the other implements. Perhaps Parent owns and creates the Child class, and thus must #import "Child.h". But, the Child also needs to call the foo:bar: method on the Parent. You could make a FooProtocol:
#protocol FooProtocol
- (void) foo: (int) arg1 bar: (BOOL) arg2;
#end
And then in Parent.h:
#interface Parent : SomeBaseClass<FooProtocol> {
}
which allows Child to do this:
#interface Child {
}
#property (assign) id<FooProtocol> fooHandler;
and use it
[fooHandler foo: 1 bar: YES];
Which leaves the child with no direct dependency on the Parent class (or Parent.h). But, this only works if you keep the declaration of FooProtocol in FooProtocol.h, not in Parent.h. Again, if this FooProtocol was only ever used by Child, then it would make sense to keep it in Child.h, but probably not if this protocol was used by classes other than Child.
So, to summarize, keep your protocols in separate headers if you want to preserve the maximum ability to separate interdependencies between your classes, or to encourage better separation in your design.
No difference. It's just a matter of how you like to organize your headers.
For example, I like to keep everything related to "one functional entity" (whatever that means, the definition varies :-)) in one file. A class that is using delegates that implement a protocol would therefore declare the class and the protocol in the same header, since they are pretty much just different bricks of the same building.
The only difference between having your protocol in a separate header file to your class's header file is it allows for including the protocol to be optional, this could aid in resolving any naming clashes, but prefixing your protocols should be the solution for that.
The convention seems to be to include relevant protocols inside the class's header file, as that way it's more organized and kept together, but if you have extremely large protocols it may make more sense to have them in separate files in order to make your class headers easier to read.

Extensions/Categories instead of Interface

So I noticed that in my new Xcode projects, by default there was a category for my class in my .m file. For example, I'll have this in the .m file:
#interface ViewController ()
#end
#implementation
//Some code
#end
I was wondering is it okay to declare my variables and functions in the category in the .m file, or should I do that in the .h file like before. Basically, what are the best practices in respect to categories.
By the way, my question is sort of related to the below link, but that link does not completely answer my question.
This is not a category, it is a class extension (notice the empty parentheses). You can keep private implementation details, including private ivars, in the extension to limit the declarations in the .h file to the interface of your class. Note that you can add ivars only in the extensions, not in categories.
One very important consequence of this approach is that if you need ivars of types that require additional headers needed only for implementation, you can avoid including that header in the header of your interface, hiding implementation dependencies from users of your class.

Header/main files in Objective C

I am reading about iOS programming and I bought the Programming iOS 4 book. There is a introductory part where among several things "Files" is mentioned.
I don't understand how the source files is put together. You have a header file with function declarations, then you have a corresponding file with the function definitions.
Let say you have a Car.h and Car.m & Person.h and Person.m.
Now, if you want to use the Car in the Person class you would import only the Car.h file. How is this sufficient? I don't understand the sequence it put together and builds a program. (Not thinking about the technical stuff, just h/m files.)
The .h or "header file" contains the interface.
The .m or "implementation file" contains the implementation.
Each implementation file is also called a "compilation unit" because the compiler compiles each one separately. Within each compilation unit, the compiler needs to know about types and methods. All it needs to know about a class to create the right code is information about the methods it implements.
So let's imagine you have these files:
Car.h
#import <Foundation/Foundation.h>
#interface Car : NSObject
- (void)drive;
#end
Car.m
#import "Car.h"
#implementation Car
- (void)drive {
NSLog(#"I'm driving!");
}
#end
Person.h
#import <Foundation/Foundation.h>
#class Car;
#interface Person : NSObject
#property (nonatomic, strong) Car *car;
- (void)start;
#end
Person.m
#import "Person.h"
#import "Car.h"
#implementation Person
#synthesize car;
- (void)start {
[car drive];
}
#end
Now when the compiler does its business, it compiles both Car.m and Person.m into Car.o and Person.o respectively. [These then get linked into the final binary, but that's beyond the scope of this question for now].
When it compiles Person.m, the compiler doesn't need to know how - (void)drive of Car is implemented, but it does need to know that it exists, that it is a method that takes no arguments and returns nothing. It doesn't care about the implementation, just that it exists. So you just need to #import the header file of Car to tell the compiler about the methods that exist on Car. The compiler knows that the implementation exists, because you've told it so, and then later on the linker will do it's business to correctly wire up the method call to the correct implementation. How the linker actually does that is a huge topic and I encourage you to go and read about it separately if you don't already understand it.
Note that it's the same for all of the standard NS classes that you use such as NSObject, NSString, etc. You just need to #import Foundation.h from the Foundation framework which tells the compiler about what these classes are and what methods are defined on them.
Creating an executable from a set of source code files is a two stage process.
Firstly, all of the .m files are individually compiled with the Objective-C compiler. This turns each one into a .o file which is an object code file. However, if the code in a .m file refers to things that are defined in other .m files, the compiler does not know about these so it just leaves unresolved references in the .o file.
The second stage is called linking. This takes all the .o files and combines them into an executable. When the linker finds unresolved references in one .o file, it checks all the others to resolve the reference.
Header files allow the compiler to have some information from outside the particular .m file it is currently compiling. So if you have two classes Foo and Bar they are conventionally defined in files Foo.m and Bar.m In order for the compiler to know what class Bar looks like when it is compiling Foo.m we put class Bars interface declaration in a header file (conventionally Bar.h) and import it into your .m file. If you see the line
#import "Bar.h"
it is literally as if the compiler has copy-pasted the entire header file into the source code file before compiling it.
What language have you been using until now? Many languages do it this way including c and c++. The m files are compiled into an actual program, and the h files provide a list of ways to interact with it. While you can still call the methods if you interact with the objective c runtime, the compiler will not guarantee their existence unless they are in the h file.
Now, I say guarantee, but if you dont provide an implementation in the m file, the sibling to the compiler, the linker will have a fit. It will try to make a jump into another m file based on its h file only to tragically discover that it is not there.
The benefits of splitting like this is that you can compile your source into a library and distribute it along with the h files and another application can use it without having the implementation source code.
In summary the m files compile into a lost island of bits and the h files are the map to get around it. If something is on the map that doesnt exist then you will get lost. If something exists but is not on the map then you will have a lot of trouble finding it.
Header files specify what messages ("methods" in other languages) can be passed to a class. That's all the compiler needs to know to compile your code; the linker will eventually wire everything up, so to speak, using the *.m files.
The compiler will handle that for you.
As you stated, a header file contains just the declarations.
Its like a interface to the actual code and that is the only thing Compiler needs to know to fetch the rest.

Importing Confusion with objective C in header File

I am new in iphone development and i have little bit Question.
My Question is When do we use #class and #import in .h (header )file.And if your answer is #class u can create instance but can not.. use its methods and by use of #import in .h file we can access all method and variable of second class .Then My Question is
if #import contains advantage then why many people used only #class in their .h file.
Please anybody have answer then reply asap.Thanks in Advance.
First of all, you're right with your assumption.
As for advantages:
The #class directive is faster, since it only discloses the Name, and the Inheritance to the Namespace (e.g. the Header File). But #import loads everything, so it's slower and means more load on the system. If your Code is a library for another system, its pretty useful if the headerfiles only load the classname (#class)
For an example. You have the class A, and are importing a Headerfile B from a library. B itself wants to use C. If it imports all data in the B Headerfile, it gets bloated, because you would load it too when importing the headerfile into your class A. But it isn't necessary, that your class A knows what Class C is capable of, because only B is using it.
Have you ever encountered cyclic imports,I suppose you are not.
The other answers are also correct but when it comes to cyclic imports the compiler gives error and you have to use #class instead of import.
quick example
//A.h
#import "B.h"
//B.h
#import "A.h"
In this case compiler will give you the error. So you have to use #class in one of the header files to remove cyclic import. It is true that #class is faster than #import but my projects doesn't have large amount of files that it would take hours to compile it :)
OK, trying to be more clear, then. This is what you usually want:
Use #class in your .h file if the header file doesn't need access to anything in the class you're importing (i.e. it only needs to know that the class exists in order to compile).
Use #import in your .m file to get access to the imported class' properties and methods.
An example, where your class Foo needs to use another class you've created, Bar. Bar also has a custom initializer, -initWithCustomValue:.
MyClass.h
#class Bar
...
Bar _instanceVariable;
MyClass.m
#import "Bar.h"
...
_instanceVariable = [[Bar alloc] initWithCustomValue:1];
This would make sure that you're not exposing unnecessary code (i.e. the contents of Bar) to other classes that might be importing MyClass.h.
From the Apple docs:
The #class directive minimizes the amount of code seen by the compiler
and linker, and is therefore the simplest way to give a forward
declaration of a class name. Being simple, it avoids potential
problems that may come with importing files that import still other
files. For example, if one class declares a statically typed instance
variable of another class, and their two interface files import each
other, neither class may compile correctly.

Objective-C when to declare what methods in #interface

When and what methods should be declared in the #interface section of a class? As I understand, methods that describe what your class does should be declared in the #interface section, but other "helper" methods should not be declared. Is this a correct understanding from my side?
One way is to declare the instance methods in .h file. And, declare the private methods inside the .m, using a Category.
For example, in MyOwnClass.h file.
#interface MyOwnClass
- (void)aInstanceMethod;
#end
And, inside your MyOwnClass.m file, before the #implementation block,
#interface MyOwnClass (MyPrivateMethods)
- (void)aPrivateMethod;
#end
You usually should add your methods to the .h file when you want an external class to have access to it (public methods).
When they're private (only used internally by the class) just put them in your .m file.
Anyway, it's just a pattern. As Objective-C works with messages, even if you don't set a method in your .h file an external file can access it, but at least your auto-complete won't show it.
You should declare all your methods in your .h
The tip from EmptyStack is nice but it's just a tip.
If you don't intend to ship your binary as an SDK, you don't really need it.
Objective-C doesn't have (yet) private methods.