SquareGeo, TriangleGeo is drived from Geo class.
Each of SquareGeo, TriangleGeo classes have drawMe methods with same parameters but different content.
I wantto call drawMe from the base class is Geo
but, issue Navigator says me a warning:
"Instance method '-drawMe' not found (return type defaults to 'id')"
in conclusion:
How can I call a method from Parent that is only defined all its child Classes.
shall I avoid warning ? should I use protocols ?
looking something like this:
[sub drawMe]; //not super
any idea ? (please do not refer me to java examples.only objectC knowhow)
Thats the beautiful thing about inheritance, you declare the method in the parent, and implement it in the children, and the underlying system handles calling the "correct" version of the method depending on what type of class the instance actually is.
The easiest way to overcome this is to provide an empty implementation in the parent class.
If you want to ensure that subclasses do provide their own implementation then you can add an exception to the base class' method
#implementation Base
- (void)drawMe;
{
[NSException raise:NSInternalInconsistencyException
format:#"You must override %# in a subclass", NSStringFromSelector(_cmd)];
}
Related
Is interface to an implementation is just like a function declaration (in a header file) to a function definition?
What if I didn't list in the interface all methods that are already implemented? What about instance variables as well?
Yes interface and implementation could be considered analogous to header and definition.
If you don't list some of the implemented methods, you won't be able to used them from other classes. Also if they are not defined in the #interface section, the compiler will complain if you try to use a function that has been implemented after the call
#implementation
- (void) functionA
{
[self functionB]; // error, because 'so far' functionB has not been defined
}
- (void) functionB
{
}
EDIT: See Martin's comment below. END EDIT
If you don't define instance variables, and you use them you'll get errors. Any variable that you use MUST be defined, either locally or in the class.
Answers to your questions:
Is interface to an implementation is just like a function declaration (in a header file) to a function definition?
YES
What if I didn't list in the interface all methods that are already implemented? What about instance variables as well?
These methods will be taken as private methods and variables which will be accessible in that particular class.
variables declared in your interface, as in 1., are visible in other classes that instantiate objects of MyClass. The variable declared in 2. will only be visible inside of MyClass. Here is something you should read: http://developer.apple.com/library/ios/#referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/
http://iosmadesimple.blogspot.in/2012/11/interface-and-implementation.html
I guess all these will help you in understanding these things in deeper.
Is it possible to initialize a property in a category?
For example, if I have a mutable array property called nameList in a class. Is it possible to have a category created for this class to add an object to the array property before any of the category method is called?
If I understand you correctly, and others are interpreting your question differently, what you have is:
A class with a property
A category on that class
And you want to call a particular method automatically before any category method is called on a given instance, that method would "initialise" the category methods by modifying the property.
In other words you want the equivalent of a subclass with its init method, but using a category.
If my understanding is correct then the answer is no, there is no such thing as a category initializer. So redesign your model not to require it, which may be to just use a subclass - as that provides the behaviour you are after.
The long answer is you could have all the category methods perform a check, say by examining the property you intend to change to see if you have. If examining the property won't determine if an object has been "category initialized" then you might use an associated object (look in Apple's runtime documentation), or some other method, to record that fact.
HTH
Addendum: An even longer/more complex solution...
GCC & Clang both support a function (not method) attribute constructor which marks a function to be called at load time, the function takes no parameters and returns nothing. So for example, assume you have a class Something and a category More, then in the category implementation file, typically called Something+More.m, you can write:
__attribute__((constructor)) static void initializeSomethingMore(void)
{
// do stuff
}
(The static stops the symbol initializeSomethingMore being globally visible, you neither want to pollute the global name space or have accidental calls to this function - so you hide it.)
This function will be called automatically, much like a the standard class + (void) initialize method. What you can then do using the Objective-C runtime functions is replace the designated initializer instance methods of the class Something with your own implementations. These should first call the original implementation and then an initialize your category before returning the object. In outline you define a method like:
- (id) categoryVersionOfInit
{
self = [self categoryVersionOfInit]; // NOT a mistake, see text!
if (self)
{
// init category
}
return self;
}
and then in initializeSomethingMore switch the implementations of init and categoryVersionOfInit - so any call of init on an instance of Something actually calls categoryVersionOfInit. Now you see the reason for the apparently self-recursive call in categoryVersionOfInit - by the time it is called the implementations have been switched so the call invokes the original implementation of init... (If you're crosseyed at this point just draw a picture!)
Using this technique you can "inject" category initialization code into a class. Note that the exact point at which your initializeSomethingMore function is called is not defined, so for example you cannot assume it will be called before or after any methods your target class uses for initialization (+ initialize, + load or its own constructor functions).
Sure, it possible through objc/runtime and objc_getAssociatedObject/objc_setAssociatedObject
check this answer
No it's not possible in objective c.Category is the way to add only method to an existing class you can not add properties in to this.
Read this
Why can't I #synthesize accessors in a category?
I am using Cocos3D and this function give me a 'may not respond' warning:
[CClayer.CC3scene someFunctionFromCC3scene];
I know one way to resolve this is to have a Function in CCLayer to make CC3scene call someFunctionFromCC3scene. But is there any other way to do this? Thanks!
More likely you're not importing the corresponding header. For example #import "CC3Scene.h". I suppose this can happen if the return type of the CC3scene property is id instead of the actual class.
Or the compiler is correct about this and it will crash with "does not respond to selector" when you run it. In that case CC3Scene does not implement the someFunctionFromCC3scene selector. Check spelling and parameters, and of course that the class actually implements that selector and has it declared in the #interface.
From the look of your example, there are several things that might be going wrong:
You might be confusing CCLayer with CC3Layer. CC3Layer is a subclass of CCLayer that supports displaying a 3D scene. Be sure you are instantiating a CC3Layer.
If you really are using a CC3Layer and the CC3Scene property (which is actually cc3Scene) is returning an instance of CC3Scene, then, as LearnCocos2D indicates, verify that the method you are invoking actually exists in the CC3Scene class. If you provide the specific method name here, then I can provide further help.
If the someFunctionFromCC3Scene is actually defined and implemented in your custom subclass, then you should cast the CC3Scene instance to your custom subclass before invoking that method:
[((MyCC3Scene*)aCC3Layer.cc3Scene) someFunctionFromMyCC3Scene];
...Bill
I'm using a Objective-C framework for game development called Cocos2d-iphone.
This is how I create a button-graphic in the game:
CCMenuItemImage *battle;
battle = [CCMenuItemImage itemFromNormalImage:#"BattleFightOption1.png" selectedImage:#"BattleFightOption2.png"
target:self selector:#selector(battleFightOption)];
Basically, when the user clicks the button, method battleFightOption runs.
But I wonder, I never did define battleFightOption in the interface.. so, my question is: when is it necessary to define a method in the interface, and when is it not?
In short, every method that is meant to be used from outside the class must be declared in the interface; methods that are internal to the class implementation are omitted. The latter are typically declared in a class extension.
When you use a selector like #selector(methodName:), methodName: is called dynamically at runtime. The compiler doesn't have to know where it is, and doesn't check that the method exists when you compile.
However, it is still a good idea to declare it privately, which is generally done by putting an unnamed category at the top of the .m file (generally referred to as a class extension):
#import "Class.h"
#interface Class ()
- (void)privateMethod;
#end
#implementation Class
...
Anything that you intend to be public, called outside of the class, should be defined in the interface. If you are going to only use #selector(battleFightOption) you really do not need to define the method anywhere but I would recommend that you add a definition in the class extension just as you would any other private method.
For a subclass, is there way I can remove/stop methods from super class implementation?
(ie. nsstring has a method length. i want to stop "mystring" class from attaining the length method).
length is a primitive method in the NSString class cluster; pretty much every other method in NSString is implemented using calls to length.
Instead of going down this path of madness, make your class a subclass of NSObject. Without a length method, it isn't really a valid NSString subclass anyway.
You can override the method to call doesNotRecognizeSelector::
- (NSUInteger)length
{
[self doesNotRecognizeSelector:_cmd];
}
But if you have to do this, you may want to rethink whether you really want to subclass in the first place. It may be better to use composition instead of inheritance if you only want to "inherit" specific behaviors/methods.
You override respondsToSelector: to return NO for the appropriate selectors and override the method to call doesNotRecognizeSelector:.
The better answer is "don't do that". Don't try removing methods, instead put an NSAssert(NO, #"don't call me") in your class's implementation, and never call it yourself.
If you must make a "thing that is like X but doesn't do Y", make a new class, and delegate behavior to an instance of the real X.
Can't you simply override the method ?
You can use doesNotRecognizeSelector:. From the documentation:
- (id)copy
{
[self doesNotRecognizeSelector:_cmd];
}
However, there's a good chance that this is the Wrong Thing To Do. The interface for a class is a contract; it states that an instance that is a kind of that class (which includes subclass instances) will accept that message. When your MyString is passed as an NSString and it doesn't accept the length message, it's violating the contract and will likely cause the program to crash, since no one would think to handle an NSInvalidArgumentException from invoking length on an NSString.