So far I have been importing the required .h files in the .h files of class where it is required.
I had read yesterday that this is the incorrect way to do it and I should forward declare the class in .h and then import it in .m However, I am confused what is the correct way to do this when it comes to large projects?
Since I will have a lot of imports in lots of files, this way it will make the code long in my opinion. Someone suggested me to create a BaseViewController class which subclasses UIViewController and add all my imports there, and all the UIViewController's that I will create will subclass BaseViewController and not UIViewController directly. This works, however I just want to know the correct way to do it.
Thanks in advance.
你可以这样做.为每一个模块创建一个.h文件,把需要用到的类导入到里面,需要引用时直接引入这个模块的.h文件使用就好.这样不用写过多的.h文件,也避免了pch的导入文件过多的情况.
you can do like this. Creat one .h fiel for everyModuel,and import you want .h file to this .h . And import this .h file to where if you want . But if something .h file is base,please import they to .pch file.
In fact, I find it a little too rampant. But, hopefully useful to you.
Simplest way to import header files in project is to create .pch file.
Create .pch and add classes header in .pch file which you want to import most frequently. Then there is no need to import those headers any of the .h and .m. They will available for them automatically.
Please refer this for how to create .pch file.
In Xcode, when you create a class, by default it will make .h and .m files of that class.
These two files are used to separate between the public and private parts of the class.
The .h file is a header file for public declarations of your class like an API, while the .m file is the private implementation.
You have to import somefile.h in somefile.m
Standard best practice for Objective-C is to forward declare classes in your .h header files and #import them in your .m implementation files. This reduces compile times and forces you to move dependencies to where they are actually required. The exception are base classes and protocols that your class inherits from. These need #imports in the header.
The Google Style Guide for Objective-C specifies a recommended order in which headers should be included in a .m implementation file. This is partly to stop headers from depending on other headers being included before them. The order goes:
Related header (e.g. MyClass.h)
Operating system headers (e.g. Foundation/Foundation.h)
Language library headers (e.g. stdlib.h)
Groups of headers for other dependencies
In general, many #imports and/or forward declarations making your code too long may be an indication that you should refactor to reduce dependencies between classes. Ideally the number of dependencies should be low, though ultimately this depends on the situation.
Related
All of my .h file in my project just have one class in each file.But I see that UIAlertController.h file has two classes :UIAlertController and UIAlertAction.Why Apple designed this and when should we combine two or more classes in one file?
.h files are header files, they contain references to all the functions you define in your .m file, so that you can share code across multiple files. You can define as many classes and functions in you .m file as you want, thus, you can reference as many classes and function as you need in your '.m' file, so you can use them in other source files. Combining two or more classes in a .h file depends on if you defined two or more classes in the corresponding .m file.
This is an interview.
There are some answers existing:
Uses #Class in .h file is enough, and using #import "" in .m file .
In header files referenced header file will at compile time is completely known file header information for all interface introduced, such as imported medical in A.H was future if import in the SubA.h A.h was, implicitly imported medical and increase unnecessary compilation, cohesion is low;
In the implementation file header files, the compiler will only need to know the type of interface information, will reduce the compile time, and the degree of coupling between the classes will be reduced.
Can and how does one ask about this issue and What is the definitely guidelines ?
The (maybe simplified) version goes like this:
If you import the header/interface file, it is like including the whole other file at that place. So typically all of your interface code is known at that place. When you are working with some classes/objects, the compiler needs to know what they are and how they are called exactly: what arguments/parameters do the methods need, what do the methods return? To answer these questions, the header files are usually included in the implmentation (.m) file.
As the implementation imports its own header file, you can often put the other imports just there. But when do you need the import in the header file? When you are declaring your interface, you often mention other types/classes, i.e. you say #proerty (strong) SomeClass *element;. Now the compiler needs to know something about SomeClass, but not all. If the compiler knows that it is another class, that will be ok at this time. In the header file, no more information is needed, so the "forward declaration" of #class SomeClass may suffice. Importing the complete header file for your other class works as well.
So where's the downside of import? There's mainly two arguments: compile time and import cycles. Consider the little example - whenever SomeClass.h changes, everything that includes it must be recompiled as well. This easily cascades through the complete code. Also, obviously, any code that imports your header file will import all their imports etc. The cycles arguments works like this. A.h imports B.h, B.h imports A.h. Depending on what's in them, one should be known before the other...
(I'd like to mention that the problems are a bit more relaxed with latest compilers but the basic argumentation still holds).
Some more notes: The #class forward declaration may be needed when you declare two types that relate to each other, i.e. a protocol that uses some class which you declare just below:
#class SomeClass;
#protocol SomeProtocol
-(void)doSomethingWith:(SomeClass *)object;
#end;
#interface SomeClass
#end
Forward declaration doesn't work for protocols the class implements or parent classes.
I am building an app, where I have made a Menu class which is a tableview being presented to the user (containing link to different view controllers, which should be presented on click).
Instead of importing any viewc. header in either of my viewc.'s I decided to import all the view controllers headers into my Menu.h. This way I can make all app navigation from menu class. I will then import menu.h in my appDelegate.h and then import only appDelegate.h to all my view controllers. Are there any unforeseen downsides to this, or should I do it another way? Thanks
If it compiles then that's OK, however it's considered best to use forward declarations in header files where ever possible to improve compile time.
Any custom type can be forward declared in the header file, of the using class, with:
#class YourViewController;
and then within the implementation file of the using class, include the actual header file:
#import "YourViewController.h"
Using forward declaration can also stop dependency loops where A.h includes B.h, which itself includes A.h.
Doing this you will have a include loop (which is bad !).
Menu.h is importing ViewController1.h
AppDelegate.h is importing Menu.h (and ViewController1.h)
ViewController1.h is importing AppDelegate.h (and Menu.h (and ViewController1.h))
A clean solution is to use Forward declaration when needed, and doing your import in .m files
Lets assume I have Class BaseClass in BaseClass.h.
I want to create a SubClass and inherit from my BaseClass , as simple as that.
BUT I want to make the inheritance in the interface of SubClass.
// SubClass.h
//#import "BaseClass.h" -I dont want to make import to the header (Better convention - I think so).
//#class BaseClass; - That will work only for declaring an instance/property.
#interface SubClass : BaseClass{
}
I also would like to keep the both classes in separate files. Do I have a simple/elegant solution for instance to group my classes in the Xcode project so they can recognize each other.
//#import "BaseClass.h"
Uncomment that line. You must import the header of the superclass in order to make this a subclass of it. I don't see what your objection was to doing that.
You have to import the superclass, otherwise your subclass has no reference of what to build off. In your subclass.h you should #import "BaseClass.h". You should not have issues with cyclical inclusion because the #import uses header guards to solve this problem.
There is one file in xcode project which is known as .pch file. In this file you can import the header files. After this no need to import in the other header files as well. But make sure the file which you import is being used in all the files.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
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"
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.
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.
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.