selector syntax: why I am getting unrecognized selector error? - ios

I have a method to compare 2 objects:
- (NSComparisonResult)compare:(NSObject *)object1 to:(NSObject *)object2{
// do some stuff
return NSOrderedSame; // or NSOrderedAscending or NSOrderedDescending
}
This method gets called like this:
NSArray *sortedSyncedAufgaben = [syncedAufgabe sortedArrayUsingSelector:#selector(compare:to:)];
Now, when I run this on my iPhone, a "unrecognized selector error" is thrown in the line with the selector:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ImpfVorgang compare:to:]: unrecognized selector sent to instance 0x14ebf040'
What is wrong? I thought for each parameter I need a colon?

sortedArrayUsingSelector: tries to apply you selector to the object on the left-hand side of the comparison, not to the class that calls sortedArrayUsingSelector:. In other words, if the selector exists in your class that initiates the sort, not in the class of the object inside NSArray (i.e. not in your ImpfVorgang class), you are going to see an "unrecognized selector error".
You can change your code to apply the selector manually, like this:
NSArray * sortedSyncedAufgaben = [syncedAufgabe sortedArrayUsingComparator:^(NSObject *a, NSObject* b) {
return [self compare:a to:b];
}];
Alternatively, you could move the comparison logic into the comparator block, and drop the compare:to: method altogether.

Related

Not casting properly?

I'm following this tutorial. And I keep getting this casting error. I've imported the Obstacle.h file in the shown class (MainScene.m). I have no idea what I'm doing wrong
- (void)spawnNewObstacle {
CCNode *previousObstacle = [_obstacles lastObject];
CGFloat previousObstacleXPosition = previousObstacle.position.x;
if (!previousObstacle) {
// this is the first obstacle
previousObstacleXPosition = firstObstaclePosition;
}
Obstacle *obstacle = (Obstacle *)[CCBReader load:#"Obstacle"];
obstacle.position = ccp(previousObstacleXPosition + distanceBetweenObstacles, 0);
[obstacle setUpRandomPosition];
[_physicsNode addChild:obstacle];
[_obstacles addObject:obstacle];
}
Error:
-[CCNode setUpRandomPosition]: unrecognized selector sent to instance 0x9a88a30
2014-04-20 10:51:28.046 FlappyFlyl[2104:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CCNode setUpRandomPosition]: unrecognized selector sent to instance 0x9a88a30'
Likely you didn't set the custom class of your root node in "Obstacle.ccb" in SpriteBuilder correctly. That's why your "Obstacle.ccb" root node is a CCNode and not an Obstacle object.
The obstacle variable does not hold an object of type Obstacle. Instead it holds an object of type CCNode. CCNode does not have a method named -setUpRandomPosition, so you get a runtime error. In Objective-C, casting is a no-op. It doesn't do anything except helping the reader of your code see the intent of the person who wrote the code.
In this regard Objective-C differs from languages like C++ or Java. Objective-C has an object system that is similar to the programming language "Smalltalk".

Im not sure why i am getting a exception when trying to pass data on segue

if([segue.identifier isEqualToString:#"CatagoryToSets"]){
BYFSetsViewController *controller = (BYFSetsViewController *)segue.destinationViewController;
//throw exception when i try to set them
controller.workOut.catagory = catagory.text;//<<UITextfield
controller.workOut.excercise = excercize.text;
NSLog(#"passing the values %# \n and %# ",catagory.text,excercize.text);
}
Im trying to pass data to the next view BYFSetsViewController WorkOut is a object that i created and has two NSStrings that i want the user to enter then pass to the next view
But i keep getting the error that it cannot write to that adress
the error message i get is
2014-03-20 19:31:11.423 Gym_Log_Book[25611:60b] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewController workOut]: unrecognized selector sent to instance 0x8d698c0'
any help would be appreciated

GenericException : Collection was mutated while being enumerated

I have searched for this problem and I know it is caused because an array is manipulated while its enumeration. Earlier in my code, I was using :
-(BOOL)busy
{
for(DataRequest* request in self.active)
if(!request.invisible)
return YES;
return NO;
}
and -(BOOL)busy is being called very frequently as the data loads from the server. Also in my code I have some lines which adds and removes objects in self.active. And because of this I was getting the exception. Then I made a change in the code as:
-(BOOL)busy
{
self.tempActive = self.active;
for(DataRequest* request in _tempActive)
if(!request.invisible)
return YES;
return NO;
}
but I am still getting the same exception. What am I doing wrong, any ideas? This is the only code where self.tempActive is used.
The exception I am getting is:
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x9ec8f60> was mutated while being enumerated.'
You need to understand the difference between classes and stack objects (like ints and things). Setting something equal to something else does not make a copy of it if it is a class. You need to use [self.active copy] instead.

ios UILabel setFrame error

#import <QuartzCore/QuartzCore.h>
- (void)viewDidLoad
{
[self.forwardView setFrame:CGRectMake(12.0, 40.0+height, 296.0, rootViewHeight-15.0)];
self.forwardView.layer.borderColor = [UIColor colorWithRed:153.0/250.0 green:153.0/250.0 blue:153.0/250.0 alpha:100].CGColor;
self.forwardView.layer.borderWidth = 1;
CGRect frame = CGRectMake(12.0f, 40.0f, 288.0f , height);
[self.tvContent setFrame:frame];
}
[self.tvContent setFrame:frame]; //crash?
Exception message:
-[__NSCFString setFrame:]: unrecognized selector sent to instance 0x7894c00
2013-05-21 10:44:54.677 Sohappy[22295:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString setFrame:]: unrecognized selector sent to instance 0x7894c00'
*** First throw call stack:
(0x1eb5012 0x19aae7e 0x1f404bd 0x1ea4bbc 0x1ea494e 0xfb407 0xfc20b 0x9d01c7 0x9d0232 0x9d04da 0x9e78e5 0x9e79cb 0x9e7c76 0x9e7d71 0x9e889b 0x9e8e93 0x8ef13f7 0x9e8a88 0x93b9 0x99df83 0x99e4ed 0x13a85b3 0x1e74376 0x1e73e06 0x1e5ba82 0x1e5af44 0x1e5ae1b 0x24e27e3 0x24e2668 0x8eeffc 0x2acd 0x29f5 0x1)
libc++abi.dylib: terminate called throwing an exception
UILabel in .xib , UseAutoLayout, ios sdk 6.1
You are trying to set the frame of an NSString - something that doesn't exist. self.tvContent is an NSString, not a UILabel as you seem to have suspected.
This is a good chance to learn how to read exceptions. I'll break it down for you here:
-[__NSCFString setFrame:]: unrecognized selector sent to instance 0x7894c00
2013-05-21 10:44:54.677 Sohappy[22295:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString setFrame:]: unrecognized selector sent to instance 0x7894c00'
*** First throw call stack:
(0x1eb5012 0x19aae7e 0x1f404bd 0x1ea4bbc 0x1ea494e 0xfb407 0xfc20b 0x9d01c7 0x9d0232 0x9d04da 0x9e78e5 0x9e79cb 0x9e7c76 0x9e7d71 0x9e889b 0x9e8e93 0x8ef13f7 0x9e8a88 0x93b9 0x99df83 0x99e4ed 0x13a85b3 0x1e74376 0x1e73e06 0x1e5ba82 0x1e5af44 0x1e5ae1b 0x24e27e3 0x24e2668 0x8eeffc 0x2acd 0x29f5 0x1)
libc++abi.dylib: terminate called throwing an exception
Here's what you are interested in:
-[__NSCFString setFrame:]: unrecognized selector sent to instance 0x7894c00
The system is giving you the class of the object and the message you tried to send it - in this case an NSString that you tried to call setFrame: on.
This information coupled with that you know which line is crashing makes for an easy conclusion: self.tvContent is an NSString where you were probably expecting a UILabel.
-[__NSCFString setFrame:]
Your app thinks that tvContent is a string, not a view. Make sure your outlet is connected to your UI correctly. Additionally, if you have a property for tvContent, it needs to be an owning reference (eg strong (under ARC) or retain (non-ARC)).

Connect to an IOS IBAction which is not at a "valid connection destination"

I have been spending days to make connection from a button on the storyboard to a new NSObject class in an IOS project. Methods I used in OS X no longer work in IOS.
I have no trouble connection the button to the IBAction on the original UIViewController class. According to the Apple documentation my new class is not a "valid connection destination".
To work around the issue I tried to call the method in the new class from the UIViewController class. I tried notification and delegate schemes, using the posts on Stack Overflow, but could not get them to work.
The closest I came linking to a +method in the target class, such as
+ (void) startToneGenerator
{
NSLog(#"Arrived in startToneGenerator");
// [self startPlay:nil];
}
However, from inside that method I can not call the -startPlay in the same class. Because the -StartPlay class is part of an audio unit construct I can not change it to a +starPlay class without breaking the audio unit.
Can anyone point me to some documentation which describes what "valid connection destination" really means, and how to make the attempted connection a valid one.
I used the method suggested in answer 1 in OS X, where it does work, but it no longer works in IOS.
I am restating the code you clarify the problem.
// code in VC
- (IBAction)RunPauseStop:(id)sender
{
NSLog(#"arrived in RunPauseSTop"); // OK
[uToneGenerator testMethod]; // OK
// [uToneGenerator startPlay:self]; // crashes
}
// code in uToneGenerator
+ (void) testMethod
{
NSLog(#"arrived in <testMethod>"); // OK
// [uToneGenerator startPlay:nil]; // crashes
}
- (IBAction)startPlay:(id)sender
{
NSLog(#"arrived in <startPlay>"); // Don't get here
}
The line [uToneGenerator startPlay:nil]; compiles (with a warning) but crashes with:
2012-03-06 13:20:25.509 Tinnitus Tamer IP[863:f803] +[uToneGenerator startPlay:]: unrecognized selector sent to class 0x6c40
2012-03-06 13:20:25.509 Tinnitus Tamer IP[863:f803] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[uToneGenerator startPlay:]: unrecognized selector sent to class 0x6c40'
calling from testMethod; compiles but crashes with:
2012-03-06 13:22:31.413 Tinnitus Tamer IP[885:f803] +[uToneGenerator startPlay:]: unrecognized selector sent to class 0x6c44
2012-03-06 13:22:31.414 Tinnitus Tamer IP[885:f803] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[uToneGenerator startPlay:]: unrecognized selector sent to class 0x6c44'
I noted that the error message can not find +[uToneGenerator startPlay:, but the method I am trying to call is -[uToneGenerator startPlay:
uToneGenerator *utg = [[uToneGenerator alloc]init]; works OK. In spite of the compiler warning "NSProject may not respond to 'startPlay'.
Thanks for helping me out. Much appreciated. I really was stuck.
You need to call whatever class method you want inside the IBAction method in your VC:
- (IBAction)myButtonPressed:(id)sender {
[MyClass myClassMethod];
}
If you want that code to work you must declare - (IBAction)startPlay:(id)sender with a +. Otherwise you will have to make an instance of your class:
uToneGenerator *utg = [[uToneGenerator alloc]init]; //or whatever you use
and then use that to call your startPlay method:
[utg startPlay:self];
Hope it helps.

Resources