Question

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

Was it helpful?

Solution

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.

OTHER TIPS

@"Some String" isn't an object, it's a string literal. You can't send messages to it. You are going to need to do something else to join those strings.

Something like:

 [NSString stringWithFormat:@"%@%@", @"String 1", @"String 2"];

Apparently, this isn't correct. String literals are treated as objects.

As mentioned in the comments, you may also have a problem with self.somestring as well. If you haven't declared a property or synthesized somestring then accessing it through self. is incorrect. You should just use

somestring = [NSString stringWithFormat:@"%@%@", @"String 1", @"String 2"];

If you've done:

@interface myClass {
  NSString *somestring;
}
@property(nonatomic, retain) NSString *somestring;
@end

And:

@implementation myClass
@synthesize somestring;
@end

Then you can access the variable using self.somestring, which is really just syntactic sugar for [self somestring].

It is important to note also that @property and @synthesize are actually syntactic sugar bits themselves. They wind up doing something similar to this.

@interface myClass {
  NSString *somestring;
}

-(NSString *)somestring;
-(void)setSomestring:(NSString *)value;
@end

And:

@implentation myClass
-(NSString *)somestring {
  return somestring;
}
-(void)setSomestring:(NSString *)value {
  somestring = value;
}
@end

So if you haven't declared somestring as a property and synthesized it, then you don't have those methods to answer the message being passed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top