objective-ciosios5objective-c-category

iOS 5: Make NSString Category include NSCFConstantString?


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-

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;
}

Solution

  • 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.