iOS 5: Make NSString Category include NSCFConstantString?
Asked Answered
P

3

12

I have an NSString category class (NSString+URLEncoding.h). I am running into and unknown selector crash, because the string I am calling the category method has been optimized into an NSCFConstantString by iOS.

-[__NSCFConstantString URLEncodedString]: unrecognized selector sent to instance 0x290174

I learned of the NSCFConstantString vs. NSCFString optimizations in iOS 5 from: http://www.cocoanetics.com/2012/03/beware-of-nsstring-optimizations/

Is anyone aware of how I can get the NSString category to include the Constant strings or even force the var to be an NSString/NSCFString and not an NSCFConstantString?

Cheers, Z

-edit-

  • Linker flags -ObjC -all_load are both already implemented
  • NSString+URLEncoding.m is included in the targets compile sources
  • NSString+URLEncoding.m implements the URLEncodedString method.
  • Checked for zombies.

I am adding a sharing service to ShareKit 2.0

header:

@interface NSString (OAURLEncodingAdditions)

- (NSString *)URLEncodedString;

implementation:

@implementation NSString (OAURLEncodingAdditions)

- (NSString *)URLEncodedString 
{
    NSString *result = (NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                                           (CFStringRef)self,
                                                                           NULL,
                                                                           CFSTR("!*'();:@&=+$,/?%#[]"),
                                                                           kCFStringEncodingUTF8);
    [result autorelease];
    return result;
}
Platyhelminth answered 10/9, 2012 at 20:0 Comment(2)
is it resolved? if not so, then i can try to resolve it if you need?Strander
The __NSCFConstantString thing in the blog you linked is a red herring. The issue in the blog has nothing to do with the subclassing and everything to do with the fact that Apple tries to optimise all empty strings to one object. If the one object representing an empty string was a simple NSString the blog's code would still be broken.Davinadavine
H
13

There's an issue with the linker that can cause its dead-code stripping to completely omit any object files that only contain obj-c categories (or that are otherwise unreferenced). Theoretically passing the -ObjC flag to the linker should fix this, but that doesn't seem to always work. You can work around this issue by providing the -all_load linker flag, which will cause the linker to always link in all object files.

Note that you might have to set -all_load on the parent project if your category is part of a sub-project or library that you-re including somewhere.

Update: I believe -ObjC is reliable now and has been for years so you can stop using -all_load for this issue.

Haga answered 10/9, 2012 at 20:7 Comment(1)
It is weird how I constantly forget this everytime I need to use one of my Objective-C libraries. This setting should be easier to use. Thanks @Kevin Ballard for your answer.Teamster
S
4

Just spent 30 minutes figuring out exactly the same issue. After fiddling with linker I found out that the category wasn't present in Compile Sources list in my target's Build Phases. Be sure to check it's there.

Separative answered 23/4, 2013 at 8:49 Comment(1)
Especially when you have multiple targets, if you forget to add new added file to multiple targets, it might cause this issue.Chanterelle
I
2

__NSCFConstantString is a subclass of NSString, so any categories on NSString apply to __NSCFConstantString too.

Either you're not linking in your category, or your category doesn't define a URLEncodedString method in its @implementation.

Inositol answered 10/9, 2012 at 20:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.