BAD ACCESS exception performSelector:WithObject: method - iphone

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.

Related

How to call a non-void function? Xcode

How do I call a non-void function? Normal [self methodName]; works. But how do I do this for a method that returns an NSString. I keep getting an error. For example:
+ (NSString *)formulateYQLRequestFor:(NSArray *)tickers
How do I call this? [self formulateYQLRequestFor]; gives me an error.
Sorry about the formatting, for some reason safari won't let me indent.
Thanks!
+ designates a class function. You call it with the class name, not an instance.
Instead of:
[self formulateYQLRequestFor:myArray];
Do this:
[MyClassName formulateYQLRequestFor:myArray];
Alternatively, you can do this:
[[self class] formulateYQLRequestFor:myArray];
You don't have to do anything with the return value if you don't want to. At least with ARC, the return value will be automatically released. However, since it's unlikely that the function does anything on its own, you probably should do something with the return value:
NSString *returnValue = [[self class] formulateYQLRequestFor:myArray];
// Do something with returnValue
Finally, if you want to call the function without passing in an array, you still need the array parameter, but perhaps the function will accept nil for the array:
NSString *returnValue = [[self class] formulateYQLRequestFor:nil];
There are two problems with your call to [self formulateYQLRequestFor];
Firstly, the method takes a parameter, which you haven't provided. Because of this, the compiler is looking for the method called formulateYQLRequestFor instead of formulateYQLRequestFor: This is significant, because the : is part of the method name in Objective-C. So you are trying to call a method that doesn't exist.
Secondly, self is sending a message to an instance of your class. The + in the method signature indicates that you have a class method, and so self does not respond to the method you are trying to call.
The correct way to do this is:
NSString *resultString = [[self class] formulateYQLRequestFor:someArray];
where someArray is a valid NSArray parameter.
I don't know what - (NSString *)formulateYQLRequestFor: does with the NSArray, but if it isn't necessary you can just call [self formulateYQLRequestFor:nil];. Alternatively you can call it with an empty array [self formulateYQLRequestFor:[NSArray array]];.

unable to know doesNotRecognizeSelector _cmd

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.

How to call a method from another method with arguments

I want to call another method from the updateButtonPressed method.
This is what I tried:
-(IBAction) updateButtonPressed{
[self loadScrollViewWithPage];
}
But the problem is that the loadScrollViewWithPage method has arguments. That method is like this:
- (void)loadScrollViewWithPage:(int)page {
}
How can I call this method?
If I understand correctly, you are wondering how to pass arguments along with messages to objects, is that right? Try:
-(IBAction) updateButtonPressed{
int foo = 4;
[self loadScrollViewWithPage:foo]; // a colon, followed by the argument
}
I suggest you read up on the Objective-C language in general, though.
http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/objectivec/introduction/introobjectivec.html
- (IBAction) updateButtonPressed{
int tempValue=5;
[self loadScrollViewWithPage:tempValue];
}

Memory management problem in GTMTest

Hello
I have a problem with the following code in a GTMTestCase:
- (void)testSomething {
myType *year = [myType valueFromString:#"1978"];
STAssertTrue([year isKindOfClass:[XBNumberAttribute class]], #"Must be subtype.");
}
If I build this (=execute the tests), I get a "segmentation fault "$TARGET_BUILD_DIR/$EXECUTABLE_PATH" -RegisterForSystemEvents, Command /bin/sh failed with exit code 139 " error. This however goes away as soon as I retain the year object (which is actually autoreleased in the valueFromString method, see below):
- (void)testSomething {
myType *year = [[myType valueFromString:#"1978"] retain];
//STAssertTrue(([year retainCount] == 2), #"Retain count wrong");
STAssertTrue([year isKindOfClass:[XBNumberAttribute class]], #"Must be subtype.");
}
Uncommenting the retainCount assertion indeed shows that the retain count is 2 at this point. However, if I put [year release] at the end of the method, the build fails again with the same error as explained above.
What is the matter here?
For the sake of completeness I include the code of valueFromString:
+ (id)valueFromString:(NSString *)pString {
return [[[myType alloc] initWithString:pString] autorelease];
}
And here the initWithString method:
- (id)initWithString:(NSString *)pString {
if (self = [super initWithString:pString]){
}
return self;
}
pointing to the following super type method:
- (id)initWithString:(NSString *)pString
{
if (self = [super init]) {
theNumber = [NSNumber numberWithInt:[pString intValue]];
}
return self;
}
After switching on all the autorelease debug options (see http://www.cocoabuilder.com/archive/cocoa/87251-how-do-debug-an-autorelease-crash.html), I found the solution:
The variable theNumber is not accessed via the property accessor, so it is not actually retained (in the initWithString of the super type method, last code snippet). As it is however receiving a release in this type's dealloc method because it is marked as a #property (retain) (information not included here, but important!), I got an error when the autorelease of the child object was called (first code snippet): it released the supertype and with it the attribute which was not there anymore.

EXC_BAD_ACCESS with Objective-C Properties

In my iPhone application, I have the following line in a constructor:
self.myVar = myVar_in;
where myVar is a property and myVar_in is a parameter passed to the constructor.
When I run the code, I get an EXC_BAD_ACCESS error on this line. However, when I replace the line with:
[myVar release];
[myVar_in retain];
myVar = myVar_in;
the code runs fine. My property is declared like this:
NSNumber *myVar;
...
#property (retain) NSNumber *myVar;
The error is consistent and I'm positive it's not a variable scope issue. Can someone explain this behavior?
EDIT: I've confirmed that myVar_in is valid right before the line(s) are executed. Here's the actual code, although it won't help much:
-(GetAddressRequestHelper*)initWithRequest:(ClientRequest*)request delegate:(id<ServerResponseDelegate>)delegate number:(NSNumber*)myVar_in location:(CLLocation*)location {
self = [super initWithRequest:request delegate:delegate];
if( self ) {
// same behavior even if this line is uncommented!!!
myVar_in = [NSNumber numberWithInt:123];
// prints "myVar_in is 123"
NSLog(#"myVar_in is %#",myVar_in);
// doesn't throw exception
/*[myVar release];
[myVar_in retain];
myVar = myVar_in;*/
// throws exception
self.myVar = myVar_in;
self.location=location;
}
return self;
}
EDIT2: I've found I still get the behavior when I explicitly initialize the param with myVar_in = [NSNumber numberWithInt:123];!
Thanks
One critical difference between this code:
[myVar release];
[myVar_in retain];
myVar = myVar_in;
and this code:
self.myVar = myVar_in;
is the use of self to call the method (setMyVar).
Almost certainly your object has been incorrectly created/allocated and self is a random value (in which case the assignment of myVar = myVar_in is scribling over random memory).
Post the code showing your object creation/init call and for good how measure how myVar_in gets its value. Also post your init code (you can (very carefully) delete extraneous code, but since this is a weird case, any extraneous code might well be relevent...
Try using the auto-generated setter method if you have #property and #synthesize statements for your variable. That will make sure the value of myVar_in is retained when assigned to myVar ([self setMyVar:myVar_in])
The error that you see is probably because myVar_in is released by the time you use it.
Make sure myVar_in is actually initialized. Would you mind posting the code where you initialize myVar_in and call the initializer method?