1

Hey experienced programmers!

Id like to ask you something about clean code :)

Id like to keep my code clean and make it nice, so thats my questions:

1)Where should I put #imports? My principles: (and i dont think that they are good)

  • #import Frameworks should be always in .h
  • #import .h files should be always in .m
  • .h files should have only @class, not imports (excluding frameworks like UIKit, etc)
  • Delegates should be in .m

    @interface ViewController() <UIAlertViewDelegate> 
    @end
    

2)Where should I put my instance variables?

  • Private and Protected variables must be in .m
  • Public must be in .h

3)Where should I put my methods?

  • Public in .h
  • Private in .m (And yeah I know that my "Private methods" are not really private, just hidden)

(btw thats pretty obvious)

4)What about #defines?

  • Global - always in .h
  • Used only in that class - always in .m

5)Where should I put NSNotification global identifiers and how to organize them

  • #define NSNotificationDataSourceDidLoadData @"NSNotificationDataSourceDidLoadData" in .h file in the class that will send this notification

But ....

  • Apple has a lot of private things in .h file
  • In most cases my .h files are just.. EMPTY :)

A year ago I had another situation - everything was in .h, but I think it is bad also

What to do? What principles are you using? Thank you!

Thats a questions about coding style, not about "how to make it compilable"

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • 6
    This is overly broad. Perhaps you could focus on a specific aspect, rather than laying down 12 sub-questions. – CodaFi Apr 25 '13 at 14:57

3 Answers3

5

Here's how I do it:

  • The usual #import <Foundation/Foundation.h> or #import <UIKit/UIKit.h> go into the .pch file. No header or implementation file is doing these imports again (makes sharing code between iOS and Mac OS X a tiny bit easier).
  • In .h files:
    • Other .h files are only imported if absolutely necessary, for example because they define types other than classes (enums, structs, everything with a typedef) which are then used in the current .h file.
    • Classes are forward declared (@class Foo;) to avoid pulling in other .h files.
    • Interfaces only contain stuff that other classes may access! No private stuff here!
  • In .m files:
    • Include all the .h files you need. But not more ;-)
    • Private instance variables and properties are defined in a class extension (@interface Foo ()).
    • Private methods don't need to be "forward declared" any more, so don't do that.

In the rare case that a class has some stuff that a few classes should access but the "normal" users shouldn't, I create foo_protected.h headers with a class category that defines the "protected" methods.

A word on #defines: avoid them if possible. Use const variables or enums instead if possible, as the additional type information can help the compiler catch more mistakes this way. For example, using enums has the nice advantage that you get a warning if you've got a switch but didn't handle all the values of the enum. If you add a new value you'll get warnings everywhere you forgot to handle them which is something you don't get with #defines.

DarkDust
  • 90,870
  • 19
  • 190
  • 224
  • +1 for mentioning the private method/function forward declaration thing; I'd forgotten about that – matt Apr 25 '13 at 15:05
  • @DarkDust Hi, I am a bit late here. But can you please cite an example in code how a class category defining "protected" can be achieved via `foo_protected.h`. Thanks in advance. – Unheilig Feb 05 '14 at 22:39
  • 1
    @Unheilig: See [How to simulate protected properties and methods in objective-c](http://stackoverflow.com/questions/13637944/how-to-simulate-protected-properties-and-methods-in-objective-c). – DarkDust Feb 06 '14 at 08:18
3

Personally, I think the answer is pretty simple. Now that instance variables can be declared in the @implementation, and properties and protocol adoptions can be declared in a class extension in the .m file, I don't put anything in a .h file that I don't absolute have to put there.

matt
  • 515,959
  • 87
  • 875
  • 1,141
2

import Frameworks should be always in .h

No, why?

import .h files should be always in .m

That's pretty vague. And what if you need to import something in a header file? You want to subclass a class, what you do? #import "SomeClass.h" in the header.

.h files should have only @class, not imports (excluding frameworks like UIKit, etc)

Brainless. (Sorry, it really is. See the reasoning above.)

2)Where should I put my instance variables?

Since other classes really aren't supposed to access ivars (i. e. it is recommended not to make your ivars public), you can put them anywhere: the header is fine (and it's useful for compatibility with the v1.0 fragile runtime API), but you can get away with placing everything in the class extension as well.

3)Where should I put my methods?

You got this one right, pretty much.

4)What about #defines?

This is good too, as far as I'm concerned. Basically, put defines and enums to the place where they need to be visible.

Apple has a lot of private things in .h file In most cases my .h files are just.. EMPTY :)

Well, even Apple isn't very consistent with their style. Be consistent.

Empty headers? If you don't need a header, don't use one. Use headers to provide interface for your classes, functions and type declarations.