I get an error when I try and import corresponding files.
i.e.
UIViewController "VC.h" Imports "CustomObject.h"
CustomObject Imports "VC.h"
Starts giving error expected specifier qualifier list before
Any ideas? I want both objects to be able to call each other.
Thanks
You have a circular dependency. You need to break the circular dependency by using a forward declaration. A forward declaration says "this is the name of something, but I don't know the full definition of it".
For example:
// In VC.h
// Forward declaration of an Objective-C class. After this, you can now use
// pointers to CustomObject, but you can't cell methods or access properties
// of those objects
#class CustomObject;
#interface MyViewController
{
CustomObject *obj;
}
#end
Then, in the implementation files, you can include both header files with no problems.
Thanks for the detailed response.
This was the solution, I just did not understand fully the first time I read it.
//VC.h calls cannot be made to CustomObject here, however there is not really any need to
#class CustomObject;
#interface VC : ViewController {
CustomObject* gameController;
// ...
//VC.m calls made in .m only.
#import "CustomObject.h"
gameController = [CustomObject init];
and vice versa in CustomObject
Sorry I didn't post this as a reply to your answer, new here :S
Related
I have a header file for an object as follows.
#import <Foundation/Foundation.h>
#interface CSSRuleSet : NSObject{
NSMutableArray *Selectors;
NSArray *Properties;
NSMutableArray *Values;
}
-(void)printElement;
-(void)initialiseArrays;
-(NSString *)getValue:(NSString *)Property;
-(void)assignValue:(NSString *)Property:(NSString *)Value;
-(void)addSelector:(NSString *)Selector;
#end
However, when I try to call methods on that object, some work, others throw up an error "no visible #interface for 'CSSStore' declares the selector 'initialiseArrays'".
The ones I am having problems with are printElement and initialiseArrays. For some reason I couldn't write a custom init function for this object either: it was there and didn't throw up any errors, it just wouldn't run.
Let me know if more information is needed. Thanks in advance!
This class is CSSRuleSet. You appear to be trying to send messages intended for this class to a different class called CSSStore. The most likely reasons would be that either you've lost track of what object you're passing around at some point or you're not managing retains and releases correctly in a non-ARC program.
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.
I'm building a custom Xcode framework, and I have a class called AXController that has a class method called showActivationWindow. showActivationWindow initializes and shows a window using AXWindowController which is a subclass of NSWindowController. Then, AXWindowController calls activate which is a class method in AXController on a button press in the window it displays.
I included AXWindowController.h in AXController.h and included AXController.h in AXWindowController.h so each could access the other's methods, but this is throwing a lot of Xcode warnings. It also seems like a very inelegant solution.
What is the correct way to solve this problem?
It's not a good idea to import header files recursively. There's a directive #class (link to Apple doc) which tells that there is a class named as such. In practice the usage is something like A.h
#class B;
#interface A:NSObject {
B* anInstanceOfB;
}
...
#end
and B.h
#import "A.h"
#interface B:NSObject {
A* anInstanceOfA;
}
...
#end
Then you can import A.h and B.h as you like from your .m file! But be careful not to make a retain cycle, if you don't use garbage collection.
Is it possible to declare a method as private in Objective-C?
If you're working in Objective-C 2.0, the best way to create methods that are "hard" for others to call is to put them in a class extension. Assuming you have
#interface MyClass : NSObject {
}
- (id)aPublicMethod;
#end
in a MyClass.h file, you can add to your MyClass.m the following:
#interface MyClass () //note the empty category name
- (id)aPrivateMethod;
#end
#implementation MyClass
- (id)aPublicMethod {...}
- (id)aPrivateMethod {...} //extension method implemented in class implementation block
#end
The advanage of a class extension is that the "extension" methods are implemented in the original class body. Thus, you don't have to worry about which #implementation block a method implementation is in and the compiler will give a warning if the extension method is not implemented in the class' #implementation.
As others have pointed out, the Objective-C runtime will not enforce the privateness of your methods (and its not too hard to find out what those methods are using class dump, even without the source code), but the compiler will generate a warning if someone tries to call them. In general, the ObjC community takes a "I told you not to call this method [by putting it in a private class extension or category or just by documenting that the method is private] and you called it anyways. Whatever mess ensues is your fault. Don't be stupid." attitude to this issue.
No, any object can send any message to any other object. You can, however, put the method in a category that's part of the class's implementation file. That way, you'll get a "Class may not implement this method" warning if you try to call it anywhere else. That's the normal way of making a method "private."
There is nothing that will prevent the method being called (since objective-c is message based anything can be sent any message), but you can declare them outside of the header so they are not visible and the compiler will generate warnings if used.
This works for both class and instance methods.
E.g.
#import "SomeClass.h"
// Interface for hidden methods
#interface SomeClass (hidden)
+(void) hiddenClassMethod;
-(void) hiddenInstanceMethod;
#end
Note: Do NOT declare variables like this or they will become class-variables - e.g. only one variable will be used by all instances.
You can do so by using categories. I've got a fuller description in my answer to this SO question.
As has been said, you can't stop anyone sending a message to a selector, but by using categories you can reduce the visibility of these functions.
Also, you can have more than one category extending a class. So, by using informative category names you can group private functions into related blocks, improving the self-documenting nature of your code.
As others mentioned, you can't have code that's
a method, and
impossible to call from outside a class.
Folks have already pointed out that you can abandon point 2, and get a method that's hard-but-not-impossible to call. Alternatively, why not abandon point 1?
static id myPrivateMethod(MyObject *me, int arg1, id arg2) { ... }
Now the code can only be called from within same file. You don't get any of the magic private-member access you can get with a method, so this is by no means a perfect solution. But there's no better way to achieve privacy.
To implement hidden methods (instance and/or class)
// ===========================
// = File: SomeClass.m
// ===========================
#import "SomeClass.h"
// =================================
// = Interface for hidden methods
// =================================
#interface SomeClass (hidden)
-(void) hiddenInstanceMethod;
#end
// ================================
// = Implementation for SomeClass
// ================================
#implementation SomeClass
-(void) hiddenInstanceMethod
{
printf( "Hidden instance method\n" );
}
-(void) msg
{
printf("Inside msg()...\n");
[self hiddenInstanceMethod];//private method calling
}
#end
http://macdevelopertips.com/objective-c/private-methods.html
reffer this link it will be helpful .
I have a hypothetical UIViewController class named "foo". foo inherits from class bar and class bar #import's "Class A", a class which foo uses extensively. The problem is, when I'm using an instance of class A in foo, I don't get any compiler errors, but I do get a warning for instance, that an instance of Class A does not respond to a particular method. Do I have to explicitly #import ClassA.h into class 'foo'? even though class foo extends extends bar, which already imports it?
Hope that's not too confusing. Let me know if I need to clear anything up.
It sounds like you have a circular dependency issue. In order to resolve it, yes, each imlementation file (.m) needs to #import the proper header file. However, if you try to have the header files #import each other, you'll run into problems.
In order to use inheritance, you need to know the size of the superclass, which means you need to #import it. For other things, though, such as member variables which are pointers, or methods which take as a parameter or return the other type, you don't actually need the class definition, so you can use a forward reference to resolve the compiler errors.
// bar.h
#class A; // forward declaration of class A -- do not to #import it here
#interface bar : UIViewController
{
A *member; // ok
}
- (A) method:(A)parameter; // also ok
#end
// bar.m
#import "bar.h"
#import "A.h"
// can now use bar & A without any errors or warnings