Why some .h file have two classes? - ios

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.

Related

Correct way to include multiple header in Objective C

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.

What is the difference between the #import "" (embedded header file) in the .h and .m files?

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.

Using Categories in Objective C

I have a file called ViewMessages.m which is becoming quite verbose. I'd like to refactor and put part of my methods into a separate file. It seems that Categories are the right way to go, so I've created a Category on ViewMessages called DataEngineViewMessages
It created 2 files, DataEngineViewMessages.h and DataEngineViewMessages.m
My Question: Do I need to #import "DataEngineViewMessage.h" in my original ViewMessage.h or .m in order to access my new methods?
Not into the .h file. The category header should import ViewMessages.h, and if required the category header should be imported into ViewMessages.m. This prevents any kind of circularity.
Usually you want to differentiate between category methods that should be public (defined in a header perhaps like ViewMessages+DataEngine.h) and category methods that are for internal use (defined in a header perhaps like ViewMessages+Private.h). The former shouldn't be included by ViewMessages and the latter should (again, in the .m file).
Any code that calls the methods will raise a compiler warning if the compiler can't see the method definition. They may also raise an error if the compiler can't figure out exactly what to do about the return type and you're expecting it to be an atomic C type.
In terms of keeping the external interface untouched, you can probably just add a #import for your category methods at the bottom of the main class's header file.

using #implementation creates "instance method conflict" warnings in XCode

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.

Why are there two #interfaces for view controllers?

I'm learning some Objective-C, specifically iOS-related stuff. Whenever I generate a new UIViewController, or UITableViewController, etc, both the generated .h and .m files contain an #interface. The application will continue to compile if I delete the #interface from the .m file, also. What is the purpose of this #interface in the .m file?
The #interface in the .m file is a class extension (a category with no name). It's now in the templates to let you put any declaration of internal methods or ivars you don't want to expose to other parts of the code.
With the advent of the modern Objective-C runtime and the progress of clang, a well written class should:
1) have only public methods in the header
2) have ivars and internal methods declared in the internal class extension
Technically, it is a "class extension" (see ("Extensions" section of) the Objective-C intro docs). In practice, it has become common to use this as a "private" interface (it is only "visible" to the file in which it exists). Objective-C does not stop anyone else from calling these methods, but they won't "see" them (think of the .h file as your public interface and this anonymous category as your private interface).
It is handy for declaring #propertys which you don't want to expose publicly.

Resources