Instance Message Error in Objective-C, What does this mean? And why is it happening? - objective-c

I get the below error hor no apparent reason, I would try to fix it myself but I can't understand what it means. Does anyone else understand it? Here is the error and below it is the code.
Error: Receiver Type 'NSdata' for instance message does not declare a method with selector type 'EncryptAES:'
I have added a comment to the line with the error on it:
//Change the Input String to Data
NSData *objNSData = [NSData dataWithData:[Input dataUsingEncoding: NSUTF8StringEncoding]];
//Encrypt the Data
[objNSData EncryptAES:Keyword.text]; //Error appears here
NSString *InputString = [[NSString alloc] initWithData:objNSData encoding:NSUTF8StringEncoding];
What does this mean, why is it happening and what can I do to fix it?
And, what is an instance message?

The problem here is that NSData does not respond to the EncryptAES: selector. You can only invoke selectors that exist on the class. With the Objective-C runtime's loose typing, you can also invoke a selector on a class that does not respond to said selector, as long as the selector appears in the implementation of at least one other class that the compiler is working with.
All standard NSData methods can be found on the NSData Class Reference. Apple has sample code for encryption, but it is not built-in to NSData.

My guess is that you're trying to use the AESEncrypt "category" for NSData, but you don't actually have the category installed in your project.

Related

Unrecongized Selector sent to Instance

Ive been through similar questions on here, but can't seem to relate it to my app!
My problem is when i run the program i get at error message
[UIView setAttString:]: unrecognised selector sent to instance 0x7538c60
Ive debugged the code down to 3 lines in the ViewController class - these are:
NSString *path = [[NSBundle mainBundle] pathForResource:#"g1" ofType:#"txt"];
NSAttributedString* text = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];
[(CTView*)self.view setAttString: text];
Im pretty sure its with the final line, but as this line has been lifted from an example app I haven't really grasped the proper understanding of what it does, and therefore can't see anything wrong with it! Any obvious or common errors I could try to resolve? I don't know how much of my code is needed for the clever folk out there to help me out - let me know and I can add more snippets!
Thanks in advance!
In human terms, that snippet is loading a string from your app's resource file, then sending it to the object referenced by self.view by means of the setAttrString: message.
The error you're seeing shows up when an object receives a message that it doesn't recognize. I don't know what a CTView is, but you should ensure that:
The CTView class does actually have a method called setAttrString:
The object referenced by self.view is actually an instance of CTView.
You can verify that latter with the following:
BOOL isCorrectClass = [self.view isMemberOfClass:[CTView class]];
...or just look at it in the debugger at runtime.
Looks like CTView response to setAttString, but your self.view is a UIView instead of CTView. And usually the self.view of a viewController is just a UIView.
If you created the view as an outlet in your IB, make sure you set it to be CTView class.
Or share where did you alloc inited the "self.view" in your last line of code.

Objective C MKMapView EXC_BAD_ACCESS

I'm a novice ObjC programmer (started learning last week); I'm having some unexpected results trying to get the lat and long from the centre of an MKMapView.
I have the following method that gets called when the map changes region:
- (void)mapView:(MKMapView*)mapView regionDidChangeAnimated:(BOOL)animated {
NSLog(#"------> %#", mapView);
latLabel.text = [[NSString alloc] initWithFormat:#"%#", [mapView centerCoordinate]];
}
In the log I'm not getting (null), I'm getting the printout of an MKMapView object; but on the very next line I get an unhandled EXC_BAD_ACCESS.
Any help appreciated, and I'd be happy to offer more info if it's requested.
Thanks.
CLLocationCoordinate2D is not an Objective-C object, it's a C structure. You can't directly convert it to an NSString like that.
Try:
CLLocationCoordinate2D center = [mapView centerCoordinate];
latLabel.text = [NSString stringWithFormat:#"(%f, %f)", center.latitude, center.longitude];
Edit: Since you're new to Objective-C, thought you might like some insight into how this problem occurs and why the error message is so non-descriptive.
[NSString stringWithFormat:...] takes a format string and an arbitrary number of parameters. It then parses the format string and fills in the parameters as they're needed.
The %# token in the format string designates an Objective-C object; i.e. an NSObject * or subclass thereof. NSObject defines the description method that provides an NSString * description of the object. stringWithFormat: calls description on the argument provided for the %# token to fill it in the format string.
The result of this is a call is made to objc_msgSend with your CLLocationCoordinate2D struct to make the description call because NSString assumes you've provided the right kind of parameter. Then the crash occurs because objc_msgSend treats the struct as if it's an NSObject * pointer and tries to access memory at a bad location. Hence the EXC_BAD_ACCESS.
Disclaimer: This is based on my understanding of Objective-C after only a couple of years, so if I'm wrong about anything, feel free to correct me.

Why is an NSString 'forgetting' what it is?

I was hoping for some help to understand why I need to re-cast my variable when it is a string from the start.
Here's the code:
+ (BOOL)hasOperandComponents:(NSString *)operandToTest
{
NSArray *componentsOfOperand = [[NSString stringWithFormat:#"%#",operandToTest] componentsSeparatedByString:#" "];
if (componentsOfOperand.count>1) return YES; return NO;
}
If I don't use the embedded call to 'stringWithFormat' then I get the rather common error:
-[__NSCFNumber componentsSeparatedByString:]: unrecognized selector sent to instance
I have been able to find answers to what this error means and hence how to avoid it (see my code above) by searching other Q's and A's... but no good explanation as to why my operandToTest seems to 'forget' that it is a NSString and become an _NSCFNumber.
I'm suspicious that it is because this is a Class method... but why would that matter when a specific instance of NSString *operandToTest is passed to the class method?
Please help?
The problem is you don't have a string to begin with. The value that you're passing into the method as operandToTest is, in fact, an NSNumber*. You need to look at the calling function to figure out why this is.

Returning an NSString from an NSError

I am using the NSURLRequest class in my iPhone app, and the method that calls it returns an NSString which is great for when the connection goes through ok, but the issue is I need to convert the NSError into an NSString so I can either return it back or run some if() statements on it.
Any ideas? :)
-[NSError localizedDescription].
(Also, every ObjC object inherited from NSObject implements -description which returns an NSString.)
for folks new to objective c (me), following is example code that makes accepted answer from 'KennyTM' work ->
[self showAlertWithTitle:#"Error:" withMessage:error.localizedDescription];
You could try the localizedDescription method, which returns a string.
More in the docs.
I found that there are three main methods to NSError:
error (NSInteger)
domain (NSString)
userInfo (NSDictionary)
To get all the error details:
NSError * err;
...
[NSString stringWithFormat:#"%#", err];

Do I need to release NSString generated using #"..."?

If I make an NSString using the code below, do I need to need to release someString?
NSString *someString = #"somestring";
No, it's a compile time constant string object, so it doesn't need releasing. It's the moral equiv of char *c = "hello world" -- where the string hello world is in global data, and you're assigning the address of this data to the pointer c.
If you created an object via a method call that contains alloc, retain, or copy, or starts with new (N-A-R-C = "narc"), then you are responsible for releasing the object. If this is not the case, then you can ignore the object.
So in the case of strings:
NSString * myString = #"This is a string";
I don't see a call there to a NARC method, so you are not responsible for releasing it. It's really that simple.
No, since it's a compile-time constant string, you do not need to release it. In fact, doing so will likely cause a run-time error.
I checked this case is different from NSString *someThing = #"someThing";
they should release urlString because of
[[NSString alloc] initWithFormat:#"%#%#", baseURLString, queryTerm];
Anywhere you use alloc/init you release it no mater what.
If it's a compile-time constant string, there wouldn't be a need to retain it as well. Is it correct?
So, please check what Apple does under the section "Insert Data Using a POST Request" at the following link:
I see a [urlString release];, why?