2

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.

5
  • 1
    Forget about where the two go. Remember that the .h will be included into the .m anyway, so it doesn't matter, from the standpoint of compiling your module. The reason for putting some stuff in the .h is so that it can be included in OTHER .m files so they can access your functions. Commented Dec 18, 2013 at 21:56
  • 2
    But this is a pretty broad question, and not possible to answer well in even a longish "answer" here. There are theoretical issues, practical/convenience issues, and issues related to what the Objective-C compiler will actually accept. These issues all get intertwined. Commented Dec 18, 2013 at 21:59
  • Ok I hadn't seen it like that. "Best practices" are always hard to argue about. I like the way you explained it though, it makes much more sense when I think about it now. Still there's a lot of magic in Objective-C IMO hehe Commented Dec 18, 2013 at 22:02
  • 2
    One problem is that any answer would start an argument between the "strict (perhaps paranoid) isolationists" and the "pragmatists" (otherwise known as "lazy jerks") over what should/shouldn't be exposed. Commented Dec 18, 2013 at 22:16
  • AFAIK, there's no way to declare properties in an @implementation block. Also, unlike your example, ivar declarations in the @implementation section have to be enclosed in curly braces. Commented Dec 19, 2013 at 0:01

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the answer, it really makes more sense. About that last question I was talking about what should I add to this part: cl.ly/image/1k303m2a3X2S/… as that'll be what I print as my reminder. Thanks again, greatly appreciated!
@protocol are another thing I haven't played with again. Is there any full list of those @* kind of tags? Thanks
Don't ever declare ivars. Thanks (:
I think @JuJoDi means always declare property instead of ivars.
2

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).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.