I'm just a newbie who follow iOS dev, and when I create new single application by using Xcode, I notice that #interface AppDelegate() being declared again in AppDelegate.m file.
but to be honest, I really don't understand why, I already see #import "AppDelegate.h" at begin of AppDelegate.m file, why couldn't I directly use #implementation AppDelegate after #import "AppDelegate.m"?
There is a difference here. The declaration of the AppDelegate Interface in the .m file is actually a class extension. Notice the () after the interface declaration.
As mentioned in the documentation:
Class extensions are often used to extend the public interface with
additional private methods or properties for use within the
implementation of the class itself.
Related
Xcode generates this template code for a new Objective-C test case. Why does it not generate a header file and puts the #interface in the implementation file?
#import <XCTest/XCTest.h>
#interface BYObjCTest : XCTestCase
#end
#implementation BYObjCTest
// test methods
#end
How is this construct called? Is this a private class? Test cases are generally not needed to be called from outside of user code, is this the reason this is generated this way?
It's ok to have the interface ClassName : Superclass block (called the class declaration block) in a .m file.
Declaring a class in a Header (.h) file is more common because it's for class that needs be public (class that will be used in other class), but if your class is not meant to be used in outside of the .m file, then it's ok to have the declaration and implementation in the same .m or .mm file.
In the test of TestClass for example, they are not used anywhere else,so no need for a header.
Other language would call those private class. Well private class in objC have no .h file :)
When I create a new single view application, the UIViewController file that is generated has an extension (I think it's an extension) in the implementation file.
//
// ViewController.m
//
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
//...
#end
And the convention seems to be that IBOutlets are declared as properties inside this extension. Why is this? What kind of behavior does this result in that is different from declaring it in the header file interface?
Properties in the header files are public, property declarations in the implementation files are private. It's up to you to choose. You can connect them directly from the interface builder into the desired file.
I can't understand your concern about extension - this code is fine. Could you explain this? (i can't comment - too less reputation, sorry)
why do I see #interface twice( inside .h and .m files in this UIViewController files I've created. the one in the .m seems to be like a constructor. is it?
.h file
#interface BlackTimer : UIViewController
#end
.m file
#interface ViewController ()
#end
usually in the .m file you put all the declarations for private methods
it's a good use to write the word "private" (or something similar) like this:
#interface ViewController (private)
-(void)myPrivateMethod;
#end
The #interface in the .m file is called a class extension. Here is a good link explaining it. Hope this helps.
And here is the Apple documentation on class extensions.
The #interface ViewController () definition in the implementation file (.m) is an anonymous Category. It allows to define ivars, properties and messages your class implements without exposing them to other objects importing your public interface (.h).
I came across the following code snippets from Apple's Documentation.
The Interface is fairly straightforward:
#import <Foundation/Foundation.h>
#import "ApplicationCell.h"
#interface CompositeSubviewBasedApplicationCell : ApplicationCell {
UIView *cellContentView;
}
#end
The implementation:
#import "CompositeSubviewBasedApplicationCell.h"
#interface CompositeSubviewBasedApplicationCellContentView : UIView {
ApplicationCell *_cell;
BOOL _highlighted;
}
#end
#implementation CompositeSubviewBasedApplicationCellContentView
//not important, abbreviated...
#end
I can't quite figure out why there is another #interface declaration in the implementation file. I assume that it is a way of declaring private instance variable. Am I right?
And since the interface already said that CompositeSubviewBasedApplicationCell extends ApplicationCell, what does CompositeSubviewBasedApplicationCellContentView : UIView mean?
Thanks in advance.
It's the definition of another class. In most cases, this would be in a separate file, but it's also possible to define multiple classes in one file, especially if they're closely related.
CompositeSubviewBasedApplicationCellContentView is probably not used by any classes except for CompositeSubviewBasedApplicationCell, so it doesn't need to have its own header file.
CompositeSubviewBasedApplicationCell and CompositeSubviewBasedApplicationCellContentView are two different classes.
I can't quite figure out why there is another #interface declaration in the implementation file. I assume that it is a way of declaring private instance variable. Am I right?
Yes, that's a way to make a class completely private. If someone wanted it to be partially private they could just extend it in the implementation file like this:
#interface CompositeSubviewBasedApplicationCell()
#end
I am trying to build the Clustering Plug in my project under Leopard. I have following two questions.
In the project an interface class is defined as
#interface ClusteringController : NSWindowController
{
.......
.....
....
}
#end.
And this class is used in implementation class using forward declaration:
#class ClusteringController;
then in one function it is used as:
- (long) filterImage:(NSString*) menuName
{
ClusteringController *cluster = [[ClusteringController alloc] init];
[cluster showWindow:self];
return 0;
}
When I build this project it produces the warning:
warning: receiver 'ClusteringController' is a forward class and corresponding #interface may not exist
Also there is one more warning produced:
warning: no '-updateProxyWhenReconnect' method found
This warning is coming for the following line of code:
if(delegate) [delegate updateProxyWhenReconnect];
Can anybody help me to overcome these warnings?
A forward declaration is used when the header file will be imported after the interface. It looks to me that you've used the #class directive after the interface for the class itself.
The normal use of a forward class declaration looks like this:
#import "SomeSuperClass.h"
#class Forwardclass;
#interface SomeClass : SomeSuperClass
{
Forwardclass anIvar;
}
#property Forwardclass anIvar;
#end
#import "SomeClass.h"
#import "ForwardClass.h"
#implementation SomeClass
#synthesize anIvar;
-(void) setAnIvar:(ForwardClass *) aForwardClass;
#end
The #class directive is never used in an implementation (.m) file.
That's not what #class is for.
You use #class in the header file for another class, to tell the compiler that the class you're declaring does exist. Without it, the compiler would not know that that's a class name, and when you declare a variable as holding a pointer to an instance of that class, the compiler would think that you're just making up words. Using #class is called forward-declaring the class.
Your situation is different. You're in the implementation file for that class.
What the compiler needs from you now is the class's #interface. The warning is telling you that the compiler needs an #interface, but you haven't given it one (so, as far it knows, the #interface “may not exist”).
Normally, you would have written the #interface in a header file; how now to get it into the implementation file?
That's where the preprocessor comes in, with its #import directive. At the top of the implementation file (ClusteringController.m), import the header file:
#import "ClusteringController.h"
The preprocessor will replace this with the contents of that file, then hand the preprocessed code to the compiler, which will see the #interface there.