views:

859

answers:

2

Hello,
I am trying to do this:

self.somestring = [@"hardcodedstring" stringByAppendingString:someotherstring];

But I keep getting:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSConcreteMutableData fastestEncoding]: unrecognized selector sent to instance 0x1fb930'

I don't call this method anywhere but I see that stringByAppendingString: calls it in my stack:

Stack: (
808221155,
806100816,
808224837,
807957033,
807851552,
812064725,
812064413,
18085, <== -[NSString stringByAppendingString:] + 109 in section LC_SEGMENT.__TEXT.__text of /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/Frameworks/Foundation.framework/Foundation
817945012,
821160740,
821157652,
821149552,
807852041,
812070519,
807836299,
807834407,
827752032,
816118388,
816157144,
8381,
8244

) How would I fix this so that it appends the string, just like it is supposed to. Thanks,
Isaac
Edit: To access somestring, I do this:

@property (nonatomic,retain) NSString *somestring;

In my ViewController.h and:

@synthesize somestring;

In my ViewController.m.
Edit: someotherstring comes from here:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
    self.somestring = [@"hardcodedstring" stringByAppendingString:[UIImagePNGRepresentation(img) encodeBase64]]; //encodeBase64 encodes it to base64
}

More Edit: I broke it up:

2009-03-20 15:14:21.389 myproject[3467:20b] *** -[NSConcreteMutableData getCharacters:range:]: unrecognized selector sent to instance 0x1fa630
2009-03-20 15:14:21.403 myproject[3467:20b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSConcreteMutableData getCharacters:range:]: unrecognized selector sent to instance 0x1fa630'
2009-03-20 15:14:21.412 myproject[3467:20b] Stack: (
808221155,
806100816,
808224837,
807957033,
807851552,
807660389,
807733601,
807733297,
807891629,
812155873,
812293801,
18081,
817945012,
821160740,
821157652,
821149552,
807852041,
812070519,
807836299,
807834407,
827752032,
816118388,
816157144,
8381,
8244
)
terminate called after throwing an instance of 'NSException'
(gdb) info symbol 18081
-[InternalChoicesController imagePickerController:didFinishPickingImage:editingInfo:] + 73 in section LC_SEGMENT.__TEXT.__text of /Users/isaacwaller/Documents/myproject/build/Debug-iphoneos/myproject.app/myproject
(gdb) info symbol 812293801
NSLog + 25 in section LC_SEGMENT.__TEXT.__text of /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/Frameworks/Foundation.framework/Foundation

So I think it is a problem with encoding the Base64 data? The code I am using is:

static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

@implementation NSData (Base64)

- (NSString *)encodeBase64;
{
if ([self length] == 0)
 return @"";

char *characters = malloc((([self length] + 2) / 3) * 4);
if (characters == NULL)
 return nil;
NSUInteger length = 0;

NSUInteger i = 0;
while (i < [self length])
{
 char buffer[3] = {0,0,0};
 short bufferLength = 0;
 while (bufferLength < 3 && i < [self length])
  buffer[bufferLength++] = ((char *)[self bytes])[i++];

 //  Encode the bytes in the buffer to four characters, including padding "=" characters if necessary.
 characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2];
 characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
 if (bufferLength > 1)
  characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
 else characters[length++] = '=';
 if (bufferLength > 2)
  characters[length++] = encodingTable[buffer[2] & 0x3F];
 else characters[length++] = '='; 
}

return [[[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES] autorelease];
}

@end

Thanks, Isaac Waller

+2  A: 
toast
Now I get: *** -[NSConcreteMutableData getCharacters:]: unrecognized selector sent to instance 0x1ed470?
Isaac Waller
In that case I would look towards self.something as well. I'll post a further description in the answer.
toast
This is incorrect. @"Some String" is an object. You can send messages to it.
Chuck
Really, my bad. I'll edit a cross out then.
toast
Yeah, that's the reason for the @"" syntax. Just using "" creates a C string literal, while @"" denotes an instance of NXConstantString. It's represented as a string literal in the app binary, but it's a true string at runtime.
Chuck
Ah, I thought that the major difference was that @"" created Unicode strings while "" was the bog standard C char[].
toast
Ah well, all those words and still way off base. :(
toast
+1  A: 

I would check the code for typos. The error pretty clearly indicates that an instance of NSMutableData is being used where an NSString is expected. It would seem that either encodeBase64 is somehow returning self or else the raw UIImagePNGRepresentation(img) is getting passed to stringByAppendingString:.

If it's not apparent, just break it down and check at each step. (I'm using NSLog for this example, but stepping with a debugger would work fine too, of course.)

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
    NSData *rep = UIImagePNGRepresentation(img);
    NSLog(@"Rep: %@", rep);
    NSString *base64 = [rep encodeBase64];
    NSLog(@"Base 64 is a %@", NSStringFromClass([base64 class]));
    self.somestring = [@"hardcodedstring" stringByAppendingString:base64]; //encodeBase64 encodes it to base64

}

My best guess is that you're accidentally passing in the raw NSData instead of an NSString — but failing that, the above code should either work correctly or show exactly where things are breaking down.

Chuck