5

Just like:

"APP_INFO" : {
            "v":"2.0",
            "appid":"1",
            "lang":"zh-Hans",
             }

I cannot use init methods because it's not a compile-time constant.

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
Yifeng Li
  • 81
  • 1
  • 5

2 Answers2

11

Starting in Clang 3.2, there's literal container syntax available:

NSDictionary * d = @{
    @"APP_INFO" :  
    @{
        @"v" : @"2.0",
        @"appid" : @"1",
        @"lang" : @"zh-Hans",
}};

This creates an ordinary immutable NSDictionary instance, just as if you had used alloc/initWithObjects:forKeys: or any other method; it's simply nice syntactic sugar.

Rumor has it that Apple will be adding this to their compiler soon, too.

jscs
  • 63,694
  • 13
  • 151
  • 195
  • Not a rumor, it states clearly on the page you linked to: "Users of Apple compiler releases can use these features starting with the Apple LLVM Compiler 4.0" ^^ – borrrden Jul 23 '12 at 03:49
  • Being syntactic sugar for a runtime initialization, you still can't make it const or put it in a header file, though. Only NSString literals can do that. – rickster Jul 23 '12 at 03:58
  • @richster, I got it. Only NSString can be made const in the header file, thx – Yifeng Li Jul 23 '12 at 04:07
  • @rickster: Why wouldn't it be able to be `const`? It's just a pointer: `NSDictionary * const d = [NSDictionary dictionary];` – jscs Jul 23 '12 at 04:11
  • @Josh Caswell, I do the same thing as [link]http://stackoverflow.com/questions/3855556/creating-a-constant-dictionary-object, but it gives me an error when init. – Yifeng Li Jul 23 '12 at 04:43
  • it tells me "initializer element is not a compile-time constant" – Yifeng Li Jul 23 '12 at 04:58
  • @Yifeng Li: Right, you can't send messages outside of a function or method. – jscs Jul 23 '12 at 05:20
  • @JoshCaswell the pointer itself can of course be made `const`. The problem here is that this syntax just gets replaced with `[NSDictionary dictionaryWith...]` under the covers, which can't be done at compile-time. – Ben Collins Oct 02 '13 at 20:11
  • Yes, that's in my answer: "This creates an ordinary immutable NSDictionary instance, just as if you had used `alloc`/`initWithObjects:forKeys:` or any other method; it's simply nice syntactic sugar.", @BenCollins. – jscs Oct 02 '13 at 20:19
  • 1
    @JoshCaswell right on. I think the question needs to be edited a little, because as written, he's asking "how do I make a compile-time constant `NSDictionary`?", the answer to which is "You can't.". He's actually asking "how do I express an `NSDictionary` as a literal?" – Ben Collins Oct 23 '13 at 16:27
1
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"2.0", @"v", @"1", @"appid", @"1", @"zh-Hans", @"lang", nil];

This creates an immutable dictionary whose contents are fixed at compile time.

You can use the same init method to populate a new dictionary at runtime:

id object1 = ...;
...
NSString *key1 = ...;
...

NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:object1, key1, object2, key2, object3, key3, nil];
Andrew Madsen
  • 21,309
  • 5
  • 56
  • 97