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
Related
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.
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.
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.
In my iOS application I have a 5 view controllers that all deal with the same feature (groups). These view controllers can be pushed on top of eachother in a few different configurations. I made a file called GroupViewHelper.h which uses #implementation to provide some functions for the groups feature. The functions look through the view controller stack and send a "refresh" message to a view controller of a specific type. The file looks like this:
#implementation UIViewController (GroupViewHelper)
- (void) refreshManageGroupsParent
{
// ...
}
- (void) refreshGroupDetailsParent
{
// ...
}
#end
My code works great and everything behaves as expected, but I get 14 warnings that are all very similar to this at build time:
ld: warning: instance method 'refreshGroupDetailsParent' in category from /Users/x/Library/Developer/Xcode/DerivedData/myapp-ayshzmsyeabbgqbbnbiixjhdmqgs/Build/Intermediates/myapp.build/Debug-iphonesimulator/myapp-dev.build/Objects-normal/i386/GroupMembersController.o conflicts with same method from another category
I think I'm getting this because I'm using a .H which is included in multiple places, but how do I correctly use #implementation in this situation?
I think I'm getting this because I'm using a .H which is included in multiple places
Well, sort of, but the real problem is that you've put the #implementation in the .h file in the first place. If you only included that .h file in one place, you would get away with it—but it would still not be the right way to do it.
but how do I correctly use #implementation in this situation?
Put it in a file called GroupViewHelper.m, and add that file to your project's sources, and put the #interface in GroupViewHelper.h.
Or, ideally, call them UIViewController+GroupViewHelper.m and UIViewController+GroupViewHelper.h, because that's the idiomatic way to name category files. (And if you use Xcode's "New File…" menu item to create a new Objective-C category file, that's what it will give you.)
In other words, interfaces and implementations for categories on existing classes work exactly the same as interfaces and implementations for new classes.
I have encountered exactly this issue. I had imported a reference to a header file, on a .m page. However, it also contained a reference to another header file, which contained a reference to another header file - that also referenced the conflicted header file. So indirectly the same header file was imported twice, causing the error.
In my case, the .m file did not need this reference. I was able to delete it, removing the error. My advice is check the files where you have included a reference to the offending header file, and verify that it actually is required.
I have an iPad application which consists of a splitviewcontroller - From the detailview of the splitview i open a modalviewcontroller(NearbyViewController) which has a button that shows a popover(RadiusViewController) with a picker. This works just fine, but when i select a value in the picker i want to call a method on the modalview controller, but i can't figure out how to do this?
My "NearbyViewController" imports the "RadiusViewController.h" because i access certain data in the "RadiusViewController", but i also need to be able to send data from the RadiusViewController back to NearbyViewController, but if i import the NearbyViewController.h file in the RadiusView then i get compilation errors due to them trying to import eachother.
This is a common problem and it's very easy to solve. The solution is simply to make the imports in the .m files instead. If you need the type to be known in the .h file, you simply use forward declaration.
#class ClassName;
It's as simple as that.
EDIT: A more thorough explanation:
Generally in the .h file the methods and properties of the class doesn't need to be known. All you need to do is tell the compiler that there is a class named ClassName. The compiler doesn't need to know anything else about the class at that point. In the .m file you will need to know the methods and properties of that class or you will not be able to use it. So in the .m file you import the class.
Just to be clear:
// SomeClass.h
#class ClassName;
// SomeClass.m
#import "ClassName.h"
This is called forward declaration. You can google it to learn more or read an introductory book on programming. It's a very basic programming concept and it's important that you learn it.