Objective c: method relation .h and .m - objective-c

I have a theoretical question: but every method and IbAction must be declared in .h??? Because if I write a method (void) in .m and not in .h the project not has problem.

If you wanna access a function from another class you're gonna import that .h header file to make your compiler understand where to find those functions and how to translate them.

It is a guideline for how to implement your classes.
Think of it in "C" terms. You define your prototypes in the .h (header) file and do the implementation in the .c or in this case the .m file.
Both ways will work, just don't redefine it in the .m...

no, they do not all need to be declared in the header.
it is common to omit the declaration from the header when attempting to make a method 'private', by categories or extensions. whether that is more or less dangerous than declaring those in the header as private is debatable, and depends on the people using your objects.
it's also good to declare a category which is not terribly relevant to the base type in a separate header.

Yeah it's no necessary to declare method in .h that because in objective c any message can be passed to any object. That's why it doesn't give any error but only a warning "ABClass may not respond to messageABC". And for a person like me who just hate warnings declare it in .h. And this is good practice as not declaring it in header is more prone to crashes as you just ignore the warnings and the instance can't handle that message and your application would say, "Hello Mr. Crash". and "Bye-Bye" to developer.

Related

Objective-C "class prototyping" [duplicate]

I'm writing a multiview app that utilizes a class called RootViewController to switch between views.
In my MyAppDelegate header, I create an instance of the RootViewController called rootViewController. I've seen examples of such where the #class directive is used as a "forward class declaration," but I'm not quite sure what this means or accomplishes.
#import <UIKit/UIKit.h>
#class RootViewController;
#interface MyAppDelegate
.
.
.
It basically tells the compiler that the class RootViewController exists, without specifying what exactly it looks like (ie: its methods, properties, etc). You can use this to write code that includes RootViewController member variables without having to include the full class declaration.
This is particularly useful in resolving circular dependencies - for example, where say ClassA has a member of type ClassB*, and ClassB has a member of type ClassA*. You need to have ClassB declared before you can use it in ClassA, but you also need ClassA declared before you can use it in ClassB. Forward declarations allow you to overcome this by saying to ClassA that ClassB exists, without having to actually specify ClassB's complete specification.
Another reason you tend to find lots of forward declarations is some people adopt a convention of forward declaring classes unless they absolutely must include the full declaration. I don't entirely recall, but possibly that's something that Apple recommends in it's Objective-C guiding style guidlines.
Continuing my above example, if your declarations of ClassA and ClassB are in the files ClassA.h and ClassB.h respectively, you'd need to #import whichever one to use its declaration in the other class. Using forward declaration means you don't need the #import, which makes the code prettier (particularly once you start collecting quite a few classes, each of which would need an `#import where it's used), and increases compiling performance by minimising the amount of code the compiler needs to consider while compiling any given file.
As an aside, although the question is concerned solely with forward declarations in Objective-C, all the proceeding comments also apply equally to coding in C and C++ (and probably many other languages), which also support forward declaration and typically use it for the same purposes.
Forward declarations are mainly to avoid circular imports, where one file imports another file which imports the first file etc. Basically when you import a file, contents of the file are substituted at the point of import when you build your project, which is then fed to the compiler. If you have circular imports, you'd have an infinite loop which would never compile. Fortunately xcode will tell you about this before trying. The forward declaration says "Don't import this class but just know that it exists. " Without either an import or a forward declaration, you get an error that no such class exists.
#class or forward class declaration(incomplete type) - just tell to a compiler that this class exists. In this case the compiler does not know anything about type memory layout - class size, members, or methods. That is why you can only use for defining classes via references and pointers.
Advantages:
reduce build time
break cyclic references

Why do I need a class extension to make a method private?

I've been reading a little bit about this and what I don't understand is why people adds class extensions to make a method private.
Wouldn't it suffice to just leave it out from the header file?
It looks to me to be enough, but I might be missing a bigger point?
Short answer: now (as of Xcode 4.4, I think), you don't. Reason: you don't need to forward declare methods. Put your private methods in your .m file, and you're done.
Previously (Xcode 4.3 and older), you had to forward declare your methods before you could call them. Because you already declared the class in the .h file, you can't declare it again in the .m file, so a class extension is the way to add methods to an already declared class.
Edit: as #Yar mentioned above (and below), a private method in a .m file that isn't declared would not be visible to subclasses of that class, meaning it would be impossible for that subclass to call or override that method. Still, I'd be inclined to just not bother declaring it, unless/until you end up with a subclass that needs to override or call it. For me this happens pretty infrequently.
It would be sufficient to leave it out of the header file, but then your subclasses don't know it's there, either. This means that you get a compiler error if you try to call these private methods. This is why you use an external file that is a class extension, and all subclasses import that extension in the .m file.
Obviously, this situation is not ideal because you get three files for each class, minimum, but the joy of Objective-C is about making LOTS of files and not worry about it. If you are scared to make files, you will end up with big classes, which is an anti-pattern.
One problem is naming the class extension file, since it's a category with no, um, category. I've been using a scheme like Blah4Subclasses, which is probably about as bad a suggestion as you'll get.
the class continuation has nothing to do with access, wrt the translation. the objc language does not specify access for methods. so it's a relatively weak private. what people end up falling back on is the ability to hide method declarations in their implementation file.
the important point to take away is that the class continuation is generally only visible to your class (because it is often placed in the *.m file). this pattern reduces the likelihood of a private method's use because it is not visible to the client, or to the compiler (in translations other than the one which contains the class' #implementation in the typical structure).
also note that the class continuation is capable of a lot -- so it's a convenient place to store your private #interface; properties, ivars, methods.
lastly, it is also a habit from earlier days, because it was a more frequent necessity. not too long ago, the declaration was added so the compiler knew the object responded to a specific selector, and the signature of that selector. because clang parses the entire #implementation block these days, many people find they do not need the declarations in the class continuation because the compiler can match methods seen in the #implementation, regardless of order of declaration.
You can add #private in your .h file.

methods in objective-c

How come sometimes you need to put the method signature in the .h file and sometimes you don't?
Methods which you are overriding from your superclass do not need to be redeclared in your class's interface. It is sometimes a good idea to do so, but is not required.
Similarly, you do not need to declare methods that you are implementing from a protocol; simply declaring that you conform to the protocol is enough.
You should declare methods which are "new" to your class: those which are not inherited from a superclass nor part of a protocol. This is to give the compiler the necessary information to determine the correct argument and return types and is necessary to the correct running of your application.
Those answerers who have said that you don't have to declare your methods are technical correct, however be aware that this is a very bad practice as the compiler will infer parameter and return types which may not match the definition and can cause undefined behavior when the method is called.
This is just because some people like to put it in the header. Some people don't. You might have notice that in the .h files there is an #interface. You technically just need to put method signatures there. But, trust me, it makes life a lot easier if its in the header file (mostly because its more readable).
Because technically objects have no methods in Objective-C as we know them from other languages, instead what you are doing is to send messages to the object, if there is a corresponding method (message) on the object with the same signature, it will be called. This means there is no real need to have the signatures in the header however it is good practice to have them so that the compiler can warn if you write the wrong signature.
It's always a good idea to declare methods in the #interface before using them (it helps the compiler, allowing the compiler to help you by catching more type errors), but the header file should really only have public methods (methods you want other classes to know about). For private methods that are used internally by the class, a class extension within the .m file is a good idea, i.e.:
#interface MyClass ()
-(void) superSecretMethod;
#end
It's always a good idea to put the signature of your public methods in the .h file. You will avoid compiler warnings, and you'll know that if you do get a warning, it's for a good reason (you mistyped your method name, parameter type, etc).

Redundant Compiler Warnings

I have found that very often, when calling myMethod asoociated with myObject1 from myObject2, I get the warning that "myObject1 may not respond to -myMethod", but then the program runs just fine anyway. Why doesn't the compiler recognize declared methods at compile time?
John Doner
This shows up as a warning because Objective-C is a very dynamic language. At compile time, the compiler hasn't found the declaration for "myMethod" (perhaps you're missing a header file, or forgot to include it in the header?) when it was attempting to compile the file. However, it only generated a warning because Objective-C has the ability to create and load extra methods at runtime so that by the time that code executes, that method will exist. Hence, it is only a warning.
Most likely you just haven't declare the method in the appropriate header file.
The warning means you're calling a method for which the compiler has not yet seen a method declaration. It is an error in most other languages, and it is certainly a warning you cannot ignore.
If you haven't declared the method, do so in an #interface block at the top of your source file (if it's a private method) or in your class's header file (if it's a public method).
If you have declared the method in a header file, be sure to import the header file.
If you have declared the method and you are importing the correct header file, you have a typo somewhere.
One case where this happens frequently is if the type of the variable that contains the object is that of a superclass, and the method is only defined for the subclass. You can avoid this by either typing it as id or making the static typing more specific. If the variable type is that of the class itself, it's likely that the method isn't visible to the compiler in the scope where you're trying to invoke it — the other answers deal with this situation.
Or sometimes, if you're using a delegate class, you need to define a category with those delegate methods in order for the compiler to find them.
Usually, adding
#class myObject1
will solve the problem. Check out Ben Gottlieb's answer to Objective-C #class vs. #import here on Stack Overflow.

#class vs. #import

It is to my understanding that one should use a forward-class declaration in the event ClassA needs to include a ClassB header, and ClassB needs to include a ClassA header to avoid any circular inclusions. I also understand that an #import is a simple ifndef so that an include only happens once.
My inquiry is this: When does one use #import and when does one use #class? Sometimes if I use a #class declaration, I see a common compiler warning such as the following:
warning: receiver 'FooController' is a forward class and corresponding #interface may not exist.
Would really love to understand this, versus just removing the #class forward-declaration and throwing an #import in to silence the warnings the compiler is giving me.
If you see this warning:
warning: receiver 'MyCoolClass' is a forward class and corresponding #interface may not exist
you need to #import the file, but you can do that in your implementation file (.m), and use the #class declaration in your header file.
#class does not (usually) remove the need to #import files, it just moves the requirement down closer to where the information is useful.
For Example
If you say #class MyCoolClass, the compiler knows that it may see something like:
MyCoolClass *myObject;
It doesn't have to worry about anything other than MyCoolClass is a valid class, and it should reserve room for a pointer to it (really, just a pointer). Thus, in your header, #class suffices 90% of the time.
However, if you ever need to create or access myObject's members, you'll need to let the compiler know what those methods are. At this point (presumably in your implementation file), you'll need to #import "MyCoolClass.h", to tell the compiler additional information beyond just "this is a class".
Three simple rules:
Only #import the super class, and adopted protocols, in header files (.h files).
#import all classes, and protocols, you send messages to in implementation (.m files).
Forward declarations for everything else.
If you do forward declaration in the implementation files, then you probably do something wrong.
Look at the Objective-C Programming Language documentation on ADC
Under the section on Defining a Class | Class Interface it describes why this is done:
The #class directive minimizes the amount of code seen by the compiler and linker, and is therefore the simplest way to give a forward declaration of a class name. Being simple, it avoids potential problems that may come with importing files that import still other files. For example, if one class declares a statically typed instance variable of another class, and their two interface files import each other, neither class may compile correctly.
Use a forward declaration in the header file if needed, and #import the header files for any classes you're using in the implementation. In other words, you always #import the files you're using in your implementation, and if you need to reference a class in your header file use a forward declaration as well.
The exception to this is that you should #import a class or formal protocol you're inheriting from in your header file (in which case you wouldn't need to import it in the implementation).
The common practice is using #class in header files (but you still need to #import the superclass), and #import in implementation files. This will avoid any circular inclusions, and it just works.
Another advantage: Quick compilation
If you include a header file, any change in it causes the current file also to compile but this is not the case if the class name is included as #class name. Of course you will need to include the header in source file
My inquiry is this. When does one use #import and when does one use #class?
Simple answer: You #import or #include when there is a physical dependency. Otherwise, you use forward declarations (#class MONClass, struct MONStruct, #protocol MONProtocol).
Here are some common examples of physical dependence:
Any C or C++ value (a pointer or reference is not a physical dependency). If you have a CGPoint as an ivar or property, the compiler will need to see the declaration of CGPoint.
Your superclass.
A method you use.
Sometimes if I use a #class declaration, I see a common compiler warning such as the following:
"warning: receiver 'FooController' is a forward class and corresponding #interface may not exist."
The compiler's actually very lenient in this regard. It will drop hints (such as the one above), but you can trash your stack easily if you ignore them and don't #import properly. Although it should (IMO), the compiler does not enforce this. In ARC, the compiler is more strict because it is responsible for reference counting. What happens is the compiler falls back on a default when it encounters an unknown method which you call. Every return value and parameter is assumed to be id. Thus, you ought to eradicate every warning from your codebases because this should be considered physical dependence. This is analogous to calling a C function which is not declared. With C, parameters are assumed to be int.
The reason you would favor forward declarations is that you can reduce your build times by factors because there is minimal dependence. With forward declarations, the compiler sees there is a name, and can correctly parse and compile the program without seeing the class declaration or all of its dependencies when there is no physical dependency. Clean builds take less time. Incremental builds take less time. Sure, you will end up spending a little more time making sure the all the headers you need are visible to every translation as a consequence, but this pays off in reduced build times quickly (assuming your project is not tiny).
If you use #import or #include instead, you're throwing a lot more work at the compiler than is necessary. You're also introducing complex header dependencies. You can liken this to a brute-force algorithm. When you #import, you're dragging in tons of unnecessary information, which requires a lot of memory, disk I/O, and CPU to parse and compile the sources.
ObjC is pretty close to ideal for a C based language with regards to dependency because NSObject types are never values -- NSObject types are always reference counted pointers. So you can get away with incredibly fast compile times if you structure your program's dependencies appropriately and forward where possible because there is very little physical dependence required. You can also declare properties in the class extensions to further minimize dependence. That's a huge bonus for large systems -- you would know the difference it makes if you have ever developed a large C++ codebase.
Therefore, my recommendation is to use forwards where possible, and then to #import where there is physical dependence. If you see the warning or another which implies physical dependence -- fix them all. The fix is to #import in your implementation file.
As you build libraries, you will likely classify some interfaces as a group, in which case you would #import that library where physical dependence is introduced (e.g. #import <AppKit/AppKit.h>). This can introduce dependence, but the library maintainers can often handle the physical dependencies for you as needed -- if they introduce a feature, they can minimize the impact it has on your builds.
I see a lot of "Do it this way" but I don't see any answers to "Why?"
So: Why should you #class in your header and #import only in your implementation? You're doubling your work by having to #class and #import all the time. Unless you make use of inheritance. In which case you'll be #importing multiple times for a single #class. Then you have to remember to remove from multiple different files if you suddenly decide you don't need access to a declaration anymore.
Importing the same file multiple times isn't an issue because of the nature of #import.
Compiling performance isn't really an issue either. If it were, we wouldn't be #importing Cocoa/Cocoa.h or the like in pretty much every header file we have.
if we do this
#interface Class_B : Class_A
mean we are inheriting the Class_A into Class_B, in Class_B we can access all the variables of class_A.
if we are doing this
#import ....
#class Class_A
#interface Class_B
here we saying that we are using the Class_A in our program, but if we want to use the Class_A variables in Class_B we have to #import Class_A in .m file(make a object and use it's function and variables).
for extra info about file dependencies & #import & #class check this out:
http://qualitycoding.org/file-dependencies/
itis good article
summary of the article
imports in header files:
#import the superclass you’re inheriting, and the protocols you’re implementing.
Forward-declare everything else (unless it comes from a framework
with a master header).
Try to eliminate all other #imports.
Declare protocols in their own headers to reduce dependencies.
Too many forward declarations? You have a Large Class.
imports in implementation files:
Eliminate cruft #imports that aren’t used.
If a method delegates to another object and returns what it gets
back, try to forward-declare that object instead of #importing it.
If including a module forces you to include level after level of
successive dependencies, you may have a set of classes that wants to
become a library. Build it as a separate library with a master
header, so everything can be brought in as a single prebuilt chunk.
Too many #imports? You have a Large Class.
When I develop, I have only three things in mind that never cause me any problems.
Import super classes
Import parent classes (when you have children and parents)
Import classes outside your project (like in frameworks and libraries)
For all other classes (subclasses and child classes in my project self), I declare them via forward-class.
If you try to declare a variable, or a property in your header file, which you didn't import yet, your gonna get an error saying that the compiler doesn't know this class.
Your first thought is probably #import it.
This may cause problems in some cases.
For example if you implement a bunch of C-methods in the header file, or structs, or something similar, because they shouldn't be imported multiple times.
Therefore you can tell the compiler with #class:
I know you don't know that class, but it exists. It's going to be imported or implemented elsewhere
It basically tells the compiler to shut up and compile, even though it's not sure if this class is ever going to be implemented.
You will usually use #import in the .m and #class in the .h files.
Forward declaration just to the prevent compiler from showing error.
the compiler will know that there is class with the name you've used in your header file to declare.
Compiler will complain only if you are going to use that class in such a way that the compiler needs to know its implementation.
Ex:
This could be like if you are going to derive your class from it or
If you are going to have an object of that class as a member variable (though rare).
It will not complain if you are just going to use it as a pointer. Of course, you will have to #import it in the implementation file (if you are instantiating an object of that class) since it needs to know the class contents to instantiate an object.
NOTE: #import is not same as #include. This means there is nothing called circular import. import is kind of a request for the compiler to look into a particular file for some information. If that information is already available, compiler ignores it.
Just try this, import A.h in B.h and B.h in A.h. There will be no problems or complaints and it will work fine too.
When to use #class
You use #class only if you don't even want to import a header in your header. This could be a case where you don't even care to know what that class will be. Cases where you may not even have a header for that class yet.
An example of this could be that you are writing two libraries. One class, lets call it A, exists in one library. This library includes a header from the second library. That header might have a pointer of A but again might not need to use it. If library 1 is not yet available, library B will not be blocked if you use #class. But if you are looking to import A.h, then library 2's progress is blocked.
Think of #class as telling the compiler "trust me, this exists".
Think of #import as copy-paste.
You want to minimize the number of imports you have for a number of reasons. Without any research, the first thing that comes to mind is it reduces compile time.
Notice that when you inherit from a class, you can't simply use a forward declaration. You need to import the file, so that the class you're declaring knows how it's defined.
This is an example scenario, where we need #class.
Consider if you wish to create a protocol within header file, which has a parameter with data type of the same class, then you can use #class. Please do remember that you can also declare protocols separately, this is just an example.
// DroneSearchField.h
#import <UIKit/UIKit.h>
#class DroneSearchField;
#protocol DroneSearchFieldDelegate<UITextFieldDelegate>
#optional
- (void)DroneTextFieldButtonClicked:(DroneSearchField *)textField;
#end
#interface DroneSearchField : UITextField
#end