unable to know doesNotRecognizeSelector _cmd - iphone

Can any one advice me what doesNotRecognizeSelect _cmd will do
- (NSDictionary*)Event:(EventBase*)eventBase
{
[self doesNotRecognizeSelector:_cmd];
return nil;
}
[self doesNotRecognizeSelect:_cmd]; There is no self method invocation but its calling, Can any one have idea about _cmd to doesNotRecognizeSelect

- (void)doesNotRecognizeSelector:(SEL)aSelector
aSelector which is _cmd
it states that method is not implemented or recognized by the receiver.
The runtime system invokes this method whenever an object receives an aSelector message it can’t respond to or forward. This method, in turn, raises an NSInvalidArgumentException, and generates an error message.
- (id)copy
{
[self doesNotRecognizeSelector:_cmd];
}
The _cmd variable is a hidden argument passed to every method that is the current selector; in this example, it identifies the selector for the copy method. This code prevents instances of the subclass from responding to copy messages or superclasses from forwarding copy messages—although respondsToSelector: will still report that the receiver has access to a copy method.

Related

Crash when calling optional protocol method

I use a protocol with some optional methods.
#protocol PhotoDropDownDelegate <NSObject>
#optional
- (void)getEditResult:(NSString *)status;
- (void)getImageForDiagram:(UIImage *)image andImagePath:(NSString *)imagePath;
- (void)dismissPhotoDropDown;
#end
I assign this for a class
photoDropDownViewController.photoDropDownDelegate = self;
I use only one method
- (void)getImageForDiagram:(UIImage *)image andImagePath:(NSString *)imagePath
{
// Make a Image on center of screen
PhotoLayer *photoLayer = [PhotoLayer nodeWithLengthOfShape:300 andHeight:200 andPathToImage:imagePath];
photoLayer.position = ccp(400, 500);
photoLayer.nameObject = [self makeNewName_ForShape];
photoLayer.isSelected_BottomRightElip = YES;
photoLayer.isSelected = YES;
[photoLayer doWhenSelected_Elip_BottomRight];
[photoLayer show_Elip];
[list_Shapes addObject:photoLayer];
[self addChild:photoLayer];
photoLayer = nil;
// Set Button Delete
selected_GerneralShapeLayer = (GerneralShapeLayer *) [list_Shapes lastObject];
[self updateStatusForButtonDelete];
}
Then the compiler show error:
[AddDiagramLayer dismissPhotoDropDown]: unrecognized selector sent to instance 0xb2a8320'
when I implement the others methods the error is disappear
-(void)getEditResult:(NSString *)status {
}
-(void)dismissPhotoDropDown {
}
As I've known, if a method in #option we can use it or not.
I don't understand what happened here. Can anyone explain to me
All the #optional directive does is suppresses compiler warnings if the optional methods are not implemented. However, if you call a method that the class does not implement, the app will still crash, as the selector (method) you tried to call is not recognised by the class, since it's not implemented.
You can work around this by checking whether the delegate implements a method before calling it:
// Check that the object that is set as the delegate implements the method you are about to call
if ([self.photoDropDownDelegate respondsToSelector:#selector(dismissPhotoDropDown)]) {
// The object does implement the method, so you can safely call it.
[self.photoDropDownDelegate dismissPhotoDropDown];
}
This way, if the delegate object implements an optional method, it will be called. Otherwise, it won't, and your program will continue running as normal.
Note that you should still use the #optional directive to denote methods that are optional to implement, in order to avoid compiler warnings when you don't implement them. This is particularly important for open source software or libraries that will be distributed to clients, as this directive tells the developers that haven't read your implementation, but can only see the header, that they don't need to implement these methods, and everything will still be fine.

BAD ACCESS exception performSelector:WithObject: method

I'm getting a EXC_BAD_ACCESS exception when I call performSelector:withObject: from a object that does implement the method I'm trying to call. Here's my code
SEL newSelector = NSSelectorFromString(#"mySelector:withCustomObject:");
[self performSelector:newSelector withObject:myCustomObject];
This causes a crash. However when I do this
[self performSelector:#selector(mySelector:withCustomObject:) withObject:myCustomObject];
it works.
Any ideas on why this is happening?
PS: none of the parameters are nil.
MORE CODE:
// My code to call this method
SEL newSelector = NSSelectorFromString(#"mySelector:withCustomObject:");
[self performSelector:newSelector withObject:self withObject:myCustomObject];
// this code is NOT called.
- (void) mySelector:(jObject *)sender withCustomObject:(jEvent *)customObject
{
NSDictionary *handlerData = [aProperty objectAtIndex:[event positionInMethodStack]];
NSString *newTitle = [handlerData objectForKey:#"newTitle"];
}
"mySelector:withCustomObject:" is the signature of a method with 2 arguments, such as
- (void)mySelector:(id)firstArgument withCustomArgument:(id)secondArgument { ... }
But you call performSelector:withObject:, which sends a message with only one argument to mySelector. The second argument is undefined, which probably causes the crash.
So if mySelector actually has 2 arguments, use performSelector:withObject:withObject:, otherwise fix the signature of the selector.

Difference between the use of withObject:self and withObject:nil

I have been wondering about the following lines of code
[self performSelector:#selector(myMethod) withObject:self afterDelay:1.0];
[self performSelector:#selector(myMethod) withObject:nil afterDelay:1.0];
Whats the difference between the above 2 lines of code.
When should we set object as nil and when should we set object as self?
In most cases I have noticed the object to be set as nil.
In the example you listed you won't experience any different behavior because your method myMethod takes no arguments. Where this is useful, is when you have a method that takes arguments.
Let's say we declared a method, squareRootMethod: that takes a NSNumber and returns the squareRoot. Then you would call [self performSelector:#selector(squareRootMethod:) withObject:numberToRoot afterDelay:1.0]
There are also methods like performSelector:withObject:withObject: for selectors that take more than one argument.
Notice the difference between these two:
#selector(myMethod)
#selector(myMethod:)
The first one is a method that doesn't take any parameters, the second is a method that takes one parameter. The withObject: part of the performSelector: method you're using allows you to pass an object into the method when it is called. However, in the case where the method doesn't take any parameters it doesn't matter because it won't be used.
The difference is whether or not you are passing an object to the selector. All the selector is doing is describing a method.
[self performSelector:#selector(myMethod) withObject:nil afterDelay:1.0];
is different from:
[self performSelector:#selector(myMethod:usingThis:) withObject:nil afterDelay:1.0];
Now if you want the selector (i.e. method) to work on some object that you pass in, say an Array, Dictionary, or class. You use withObject. As in:
[self performSelector:#selector(myMethod:) withObject:myDictionary afterDelay:1.0];
-(void)myMethod:(NSDictionary*)dictionary
{
// Do something with object
}
You could pass in anything including a reference to the current class (e.g. self), as you did in your example.
In the first example, you passed self as the argument to pass to the method when it is invoked. But your method takes no arguments, so it is unnecessary fluff.
In the second example, you passed nil, so the method is passed nil to it's non-existent arguments and then terminates. This is more "efficient" in the sense that because your method takes no arguments, and `nil. Is the object equivalent of NULL, then you pass less fluff through that is ignored anyhow.

Is this how one method calls another method?

I'm doing some programming and I'm also reading some code at the same time and I come across this code
-(id)init
{
if ((self = [super init]))
{
some code....
[self initEnemy];
}
return self;
}
and below that it has
-(void)initEnemy
{
more code....
[self resetEnemy];
}
and then..
-(void)resetEnemy
{
more code.. etc..
}
The way I see it is the first method called init calls on the method initEnemy and that in turn calls on resetEnemy. Basically one method brings on the other and so on.
Successfully forming an algorithm (you can't really tell because i've shown little code). Am I looking at it the right way?
Also, could I have an explanation on what happens inside the -(id)init method when return self; is performed.
Yup, you're reading that sequence of execution correctly.
When "return" happens in a method, control returns to the "caller" method (whoever originally called it in the first place). The "self" is there to indicate that the value of "self" should be handed back to the caller. (In this case, "self" refers to the instance of the object being initialized in the -init. If you want to know more about initializers, you can break it down into more specific questions.)

Objective-C performSelector when to use colon?

Do you only postfix the method name with a : if you are calling a foreign object?
For some reason
[self performSelector:#selector(myMethod:) withObject:nil afterDelay:5];
Does not work but
[self performSelector:#selector(myMethod) withObject:nil afterDelay:5];
Does!
EDIT:
Declared in the implementation of a class but not the interface.
- (void)myMethod
{
// Some stuff
}
The colon represents a method argument. Since myMethod takes no arguments its selector can't have a colon. If you had multiple arguments like this...
- (void)myMethod:(id)method object:(id)object enabled:(BOOL)bool {
// Some Stuff
}
... the selector would be #selector(myMethod:object:enabled:)
In Objective-C the colons are part of the method name. That is, myMethod and myMethod: are distinct selectors (and in your case, only the latter exists).
For instance, for a method declared like:
-(void)doSomethingWithFoo:(int)foo andBar:(int)bar;
The selector is doSomethingWithFoo:andBar:.