2

As you know Apple has provided @ literals for such classes as NSNumber, NSDictionary, NSArray, so we can create an object this way, for example

NSArray *array = @[obj1, obj2];

So I wonder, if there is a way to create such literals for my own classes? For example, I want to write smth. like

MyClass *object = MyClass[value1, value2];

And I don't want to write long parsers :)

Jay Patel
  • 657
  • 1
  • 6
  • 14
Catherine
  • 182
  • 7
  • 1
    Not sure if it's 100% what you want but try subscripting http://nshipster.com/object-subscripting/ – BooRanger Jul 18 '13 at 09:13
  • 1
    @BooRanger this is really cool!! thanks! But, as I've understood I can add/replace/get values for index/key by overriding in my class given methods, but I can't initialize the object of my class the way it used for arrays/dictionaries? – Catherine Jul 18 '13 at 10:36
  • No, you cannot initialize object in a literal way, but it is still cool even that the Subscripting exists :-) It can save you some writing, but I'm afraid that, in practice, it can cause a lot of troubles because of code "unreadability". Lets be honest: there is a big chance that any programmer who will open your project (when you are on holiday etc.) will have no idea something like Subscripting exists and will be really scared of code expressions he/she never seen before :-) – Lukas Kukacka Jul 18 '13 at 13:06
  • @LukasKukacka I agree, but 1)I can comment my code 2) I'm the only programmer on this project 3) It lokks really cool, so let make everybody study this style :) – Catherine Jul 18 '13 at 13:23
  • @Catherine I edited my answer to include short example of subscripting implementation just in case anyone finds this and will be interested in implementing subscriptions :-) – Lukas Kukacka Jul 18 '13 at 13:27

2 Answers2

2

@ syntax are literals, which is feature of Clang compiler. Since its compiler feature, NO, you cannot define you own literals.

For more informations about compilers literals, please refer Clang 3.4 documentation - Objective-C Literals

Edit: Also, I just found this interesting SO discussion

Edit: As BooRanger mentioned at the comments, there exists method to create [] accessors (the Collection Literals way) to access custom objects. Its called Object Subscripting. Using this, you can access anything in your custom class like this myObject[@"someKey"]. Read more at NSHipster.

Here is my example implementation of "Subcriptable" object. For example simplicity, it just accesses internal dictionary. Header:

@interface LKSubscriptableObject : NSObject

//  Object subscripting
- (id)objectForKeyedSubscript:(id <NSCopying>)key;
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key;

@end

Implementation:

@implementation LKSubscriptableObject {

    NSMutableDictionary     *_dictionary;
}

- (id)init
{
    self = [super init];
    if (self) {
        _dictionary = [NSMutableDictionary dictionary];
    }
    return self;
}

- (id)objectForKeyedSubscript:(id <NSCopying>)key
{
    return _dictionary[key];
}

- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key
{
    _dictionary[key] = obj;
}

@end

You can then access to anything in this object simply using square brackets:

LKSubscriptableObject *subsObj = [[LKSubscriptableObject alloc] init];

subsObj[@"string"] = @"Value 1";
subsObj[@"number"] = @2;
subsObj[@"array"] = @[@"Arr1", @"Arr2", @"Arr3"];

NSLog(@"String: %@", subsObj[@"string"]);
NSLog(@"Number: %@", subsObj[@"number"]);
NSLog(@"Array: %@", subsObj[@"array"]);
Community
  • 1
  • 1
Lukas Kukacka
  • 7,604
  • 2
  • 25
  • 50
1

Are you okay with this syntax?

MyClass *object = MyClass(value1, value2);

Just define macro like this:

#define MyClass(objects...) [[MyClass alloc] initWithObjects: @[objects]];

Compiler will allow class named MyClass and MyClass() macro.

Tricertops
  • 8,492
  • 1
  • 39
  • 41