I have method overriding like below. Please ignore the way i written it may not be perfectly written, just for sample. But i want to know what would the output if i method overridden like this for variable "a".
-> base class
#interface A
{
int a=15;
}
-(int) myFunction;
#end
-> derived class
#interface B : A
{
int a=10;
}
-(int) myFunction;
#end
Lets image "myFunction" returns "a". Since, it does method overriding, when i call like,
B bObj;
bObj.a = ?
What should be the output 10 or 15 ?
I have assumed you are aware you can't declare variables in a header like that and the initialisation there is just for simplicity.
Similarly, your B bObj hasn't been initialised and isn't a pointer
bObj.a would return 10. So would [bObj myFunction]. You have overridden the method and told the compiler to disregard previous implementations of this method and use the new one.
Can you suggest what the output of this might be:
A *obj = [[B alloc] init];
NSLog(#"%d", [obj myFunction]);
or this:
B *obj = [[A alloc] init];
NSLog(#"%d", [obj myFunction]);
if child and parent both will return A then its method overriding ... but if class A's myFunction: returns A and class b's myfunction returns B or any reference type return type which has the same relation what ever there classes have means Parent and child relationship then this also know as overriding
Related
I am using XCode 4.0.2 for a iOS4 project.
I have this class method that construct an object. This is a constant that i need occasionally from start to end of the app.
However, running the Analyze tool this gives me a "Potential leak of an object" warning for the c object.
Should I be concerned? How can I fix it?
Thank you
You should read the Memory Management Programming Guide provided by Apple.
You should prefix your method name (+[XYZ A] in this instance) with new to make it clear that callers of your method know that they are responsible for releasing the object they receive. You would rename the method to +[XYZ newA].
If you do not wish to rename your method, you should at least return an autoreleased object, e.g. change the last line to return [c autorelease];
Every time you use that method, it creates a new instance of XYZ through the (deprecated) +new method.
If you want a single object of class XYZ that persists to the end of the app, you'll need to make some changes. The simplest way is to create this object on class initialization. In the .m file for whatever class we're looking at here, add the following:
static XYZ *instance = nil;
+ (void)initialize {
if (self != [ThisClass class])
return;
instance = [[XYZ alloc] init];
instance.X = ...;
instance.Y = ...;
instance.Z = ...;
}
And then, your A method:
+ (XYZ *)A {
return instance;
}
I have imported my .h file into a 2nd one, but in the 2nd one i'm trying to do:
FirstClass *firstClass = [FirstClass alloc] init];
[firstClass iconWithType:test];
To match this:
-(void)iconWithType:(NSString *)iconType
But it's not listing iconWithType as a suggestion and i get a warning saying it might not respond to that.
How can i get this to work properly?
My FirstClass is a UIView.
In your FirstClass.h file do you have the method definition in the interface?
I.e.
#interface FirstClass : NSObject {
}
- (void)iconWithType:(NSString *)iconType;
#end
Additionally, the name of the method implies something should be returned. However, it is marked as void.
I'm guessing you just have a return type mismatch. Take a look: does -iconWithType: actually return void? or does it return a UIImage or something else besides?
I would like to detect taps with a tapRecognizer in one class that triggers another class to create an object of a third class.
How Can I trigger this method from the tap detecting class without creating a new object of the second class?
Or would creating a new object of this second class be fine? It would lose all of its old data though.
How is triggering like this done? I tried something but it just warned about an object is being accessed in a class method.
e.g.
ViewController Class 1
+(void) setupClass2
{
Class2 class = .........
class.someValue = ......
self.navigationController pushViewController:class ......
}
// The calling/trigger class should be able to invoke the setupClass function e.g.
[Class1 setupClass];
How is this done correctly?
You have to declare a protocol with methods like this:
-(void) class1:(Class1*) c didReceivedTouch:(UITouch*) e; //or any other params that you need
Then you assign a delegate that conforms to that protocol (class 2 in your case). Create the class 3 object in that callback.
Declare a protocol with method suggested by Max
#protocol UrProtocolName
#required/#optional
-(void) class1:(Class1*) c didReceivedTouch:(UITouch*) e; //or any other params that you need
#end
Then implement the protocol in your second class
#interface 2ndClass < UrProtocolName>
.....
#end
#implementation 2ndClass
-(void) class1:(Class1*) c didReceivedTouch:(UITouch*) e
{
3rdClass class = .........
self.navigationController pushViewController:class animated:YES];
}
#end
But I really don't understand why do you want to gor for 2nd Class, when all you want is to create object of 3rdClass and push it on navigationController. You can have 2ndClass' object as a member of firstClass initialized while constructing the object of 2ndClass, and den you can have one method in 2ndClass which will simple create an object of 3rdClass, and you can call this method of 2ndClass object as many times, till your firstClass object is in scope.
This is an objective-c question.
I would like to call a method in an object, but there is no instantiation of the object. Is this possible?
The method I want to call is not a class method.
You can't call a method on an object that doesn't exist. But you can call a method on a class even if you have no instantiated objects of that class. (That's what alloc is in #fbrereton's answer -- a class method).
Class methods are declared and defined with a + instead of a -, are called on the class rather than the instance, and cannot access self or any instance variables in the class (for reasons that should be obvious).
Unless the method is static you will not be able to do this. static routines in Objective-C will be prepended with a +. For example NSObject provides these two routines (among many):
+ (id)alloc; // static - an NSObject instance is not required
- (NSString*)description; // nonstatic - an NSObject instance is required
One would make the respective calls like so:
NSObject* result = [NSObject alloc];
NSString* desc = [result description];
Sorry to nit-pick Chris' terminology, but we don't call a method on an object in Objective-C, we send a message to an object. When you send a message, the runtime will look up the appropriate method and call it. The distinction matters.
Perhaps you just want a plain-old C function. If you don't want a class method, and you don't want an instance method, that appears to be your only option. Don't be afraid of using C functions in Objective-C. Every technique has its place.
You can indeed invoke an instance method without an instance, provided it is functionally a class method (that is, it accesses no instance variables). Here's an example:
/*
Compile with:
gcc -framework Foundation inst_method_without_inst.m -o inst_method_without_inst
*/
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#interface Foo : NSObject {
}
- (BOOL)doSomethingWithThis:(NSString *)this;
#end
#implementation Foo
- (BOOL)doSomethingWithThis:(NSString *)this {
NSLog(#"Look, it's this: %#", this);
return YES;
}
#end
typedef BOOL (*my_sel_t)(id, SEL, NSString *);
int
main(void) {
Class cls = [Foo class];
SEL my_sel = #selector(doSomethingWithThis:);
Method m = class_getInstanceMethod(cls, my_sel);
// You could also use +[NSObject instanceMethodForSelector:] to get |m|,
// since |cls| is a kind of NSObject.
my_sel_t f = (my_sel_t)method_getImplementation(m);
BOOL result = f(nil, my_sel, #"Hello from an instanceless instance method invocation!");
NSLog(#"result: %d", (int)result);
return EXIT_SUCCESS;
}
You could get it to work even if the instance method accesses instance variables by allocating memory for it to work with (using either +alloc or class_getInstanceSize() plus malloc()) and passing a pointer to that memory as the first id argument to the implementation instead of nil.
While this is entertaining as an exercise, I can't think of a good reason to not just instantiate the class and use the standard messaging syntax and compiler support. In fact, the only reason we couldn't just do [(Foo *)nil doSomethingWithThis:#"BOO!"] here is that objc_msgSend() special-cases messages to nil with the result that NO is returned and nothing happens.
Example:
I have 10 view controllers, which are all allocated and initialized in the same way:
UIViewController *controller = [[MyViewController alloc] initWithNib];
(note that -initWithNib is a custom method of a UIViewController subclass)
The next view controller class is OtherViewController, and so on. I want to load the view controllers lazily, just when I need them. But to do that, I need to have some kind of "array" that will give me the corresponding class for a given index, so that I can initialize it.
I ended up creating a method with a big switch-statement, that will just do that nasty allocation and initialization separately for every single view controller. I'm not happy with that. There it would be much better if I could assign the appropriate class to a variable, and then at the end of the switch statement just allocate and initialize that class from the variable.
Is there a way to achieve that?
EDIT: I've found a function
id class_createInstance(Class cls, size_t extraBytes)
and every class seems to have a property "class". But I can't assign it to an instance variable. This doesn't work:
Class cls = [UIImage class];
cls *image = [cls imageNamed:#"avatar.png"];
The first line compiles. But the second one gives an error: "image undeclared".
If you know the names of the classes at compile time, you can assign the classes to Class variables. For example:
static Class factory[2];
factory[0] = [MyViewController1 class];
factory[1] = [MyViewController2 class];
...
Then you could have (classid would be a constant known at compile time that would map to a desired class:
-(UIViewController*)createViewController:(int)classid
{
return [[factory[classid] alloc] init];
}
Assuming that method is defined in a class named MyFactory, you can then do:
MyFactory * fac = [[MyFactory alloc] init];
UIViewController * v1 = [fac createViewController: 0]; // typed
id v2 = [fac createViewController: 1]; // untyped
If you don't have the compile time name of the class, you can simply do the following:
#include <objc/objc-runtime.h>
id object = [[NSClassFromString(#"TheClassName") alloc] init];
Since your original question involves a set of UIViewControllers though, there's no reason to lose type safety with the latter method.
You want to use reflection:
id controller = class_createInstance(NSClassFromString(#"your class name"), 0/*extra bytes*/);
Objective-C Runtime Reference
I blogged about this last month at:
http://igotosoft.blogspot.com/2009/05/dynamically-creating-viewscontrollers.html
Essentially, it involves a new class I call the ClassConstructor, which takes a class name, init method name, and comma separated arguments. When you need to create an instance of that class, just use your [myClassConstructor create];
What you want is Reflection. No idea of objective-c has it though - but the term might help you Google for your answer better.
The Objective C Reference also will be a good place to look to get the calls. Try searching for Objective-C 2.0 Runtime Reference since I cant add links