Can the new Clang Objective-C literals be redirected to custom classes?

后端 未结 2 924
小蘑菇
小蘑菇 2020-11-30 03:17

Although the overloading of @ begins to tread on dangerous territory, I love the addition of the new Objective-C literals in Clang 3.1. Unfortunately the new li

相关标签:
2条回答
  • 2020-11-30 04:05

    The comments have it all correct, but just to summarize:

    • No.

    The meanings of Apple's @{}, @[], and @"" literals are hard-coded into Clang. You can see it here: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/NSAPI.cpp?view=markup It's all fairly modular, meaning that it wouldn't be hard for a Clang hacker to add her own literal syntax... but "modular" doesn't mean "accessible from the outside". Adding a new syntax or even redirecting the existing syntax to new classes would definitely require rebuilding Clang yourself.

    Here's a blog post about adding NSURL literals to Clang by hacking on its internals: http://www.stuartcarnie.com/2012/06/llvm-clang-hacking-part-3.html (Thanks @Josh Caswell)


    If you're willing to use Objective-C++ with C++11 extensions, you can has "user-defined literals", which allow you to write things like

    NSURL *operator ""URL (const char *s) { return [NSURL URLWithString: @(s)]; }
    
    int main() {
        ...
        NSURL *myurl = "ftp://foo"URL;
        ...
    }
    

    This was mentioned in the comments on Mike Ash's blog. http://www.mikeash.com/pyblog/friday-qa-2012-06-22-objective-c-literals.html But this doesn't look very Objective-C-ish (or very C++ish!), and it works only with an Objective-C++11 compiler, and in general please don't do this. :)

    0 讨论(0)
  • 2020-11-30 04:12

    You can substitute class for some Objective-C literals with @compatibility_alias keyword trick.

    Here's an example.

    @compatibility_alias NSNumber AAA;
    

    Of course, you should provide proper implementation for new class.

    #import <Foundation/NSObject.h>
    
    @interface  AAA : NSObject
    + (id)numberWithInt:(int)num;
    @end
    
    @implementation AAA
    + (id)numberWithInt:(int)num
    {
        return  @"AAAAA!!!";    // Abused type system just to check result.
    }
    @end
    
    @compatibility_alias NSNumber AAA;
    

    Now Clang will do the job for you. I confirmed this is working for number, array, dictionary literals. Unfortunately string literals seem to be emitted statically, so it won't work.

    For more information about @compatibility_alias keyword, see here.

    Note

    Because @compatibility_alias keyword is a compiler directive which applies to current compilation unit, you need to separate compilation unit to avoid symbol duplication with NSObject class in Apple's Foundation Kit. Here's how I did it.

    main.m

    #import "test.h" // Comes before Foundation Kit.
    #import <Foundation/Foundation.h>
    
    int main(int argc, const char * argv[])
    {
        @autoreleasepool
        {
            NSLog(@"return of test = %@", test());
            // insert code here...
            NSLog(@"Hello, World!");
    
        }
        return 0;
    }
    

    test.h

    id test();
    

    test.m

    #import "test.h"
    #import <Foundation/NSObject.h>
    
    @interface  
    AAA : NSObject
    + (id)numberWithInt:(int)v;
    + (id)arrayWithObjects:(id*)pobj count:(int)c;
    + (id)dictionaryWithObjects:(id*)pvals forKeys:(id*)pkeys count:(int)c;
    @end
    @implementation AAA
    + (id)numberWithInt:(int)v
    {
        return  @"AAAAA as number!!!";
    }
    + (id)arrayWithObjects:(id*)pobj count:(int)c
    {
        return  @"AAAAA as array!!!";
    }
    + (id)dictionaryWithObjects:(id*)pvals forKeys:(id*)pkeys count:(int)c
    {
        return  @"AAAAA as dictionary!!!";
    }
    @end
    
    
    
    @compatibility_alias NSDictionary AAA;
    @compatibility_alias NSArray AAA;
    @compatibility_alias NSNumber AAA;
    
    
    
    id test()
    {
    //  return  @{};
    //  return  @[];
        return  @55;
    }
    

    Result.

    2013-03-23 08:54:42.793 return of test = AAAAA!!!
    2013-03-23 08:54:42.796 Hello, World!
    
    0 讨论(0)
提交回复
热议问题