开发者

Objective-C dot notation with class methods?

开发者 https://www.devze.com 2022-12-22 07:23 出处:网络
Note, I\'m specifically referring to the fact that dot notation is being used with class methods, not instance methods.

Note, I'm specifically referring to the fact that dot notation is being used with class methods, not instance methods.

Out of curiosity, I wanted to see what would happen if I tried to use Objective-C dot notation syntax with a class method. My experiment was as follows:

#import <Foundation/Foundation.h>

static int _value = 8;

@interface Test : NSObject

+ (int) value;
+ (void) setValue:(开发者_StackOverflow社区int)value;

@end

@implementation Test

+ (int) value {
    return _value;
}

+ (void) setValue:(int)value {
    _value = value;
}

@end

int main(int argc, char * argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSLog(@"Test.value: %d", Test.value);
    NSLog(@"[Test value]: %d", [Test value]);

    Test.value = 20;
    NSLog(@"Test.value: %d", Test.value);
    NSLog(@"[Test value]: %d", [Test value]);

    [Test setValue:30];
    NSLog(@"Test.value: %d", Test.value);
    NSLog(@"[Test value]: %d", [Test value]);

    [pool release];

    return 0;
}

I was surprised to see that this was compiled, let alone executed with what is, I suppose, correct behavior. Is this documented somewhere, or just a fluke of the compiler?

I compiled using GCC on Mac OS X 10.6:

gcc --version: i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659) 

compile using: gcc ObjCClassDotSyntax.m -framework Foundation -o ObjCClassDotSyntax
run: ./ObjCClassDotSyntax

output:
2010-03-03 17:33:07.342 test[33368:903] Test.value: 8
2010-03-03 17:33:07.346 test[33368:903] [Test value]: 8
2010-03-03 17:33:07.351 test[33368:903] Test.value: 20
2010-03-03 17:33:07.352 test[33368:903] [Test value]: 20
2010-03-03 17:33:07.353 test[33368:903] Test.value: 30
2010-03-03 17:33:07.353 test[33368:903] [Test value]: 30


This is correct behavior. foo.method is syntactic sugar for [foo method]—a straight conversion with identical semantics. Similarly foo.prop = bar is syntactic sugar for [foo setProp:bar], again with identical semantics. This transformation is implemented in the compiler. Thus you can use dot notation to call 0-parameter methods as in foo.doSomething instead of [foo doSomething]. Of course, if you do this, you are evil.

The fact that the callee is a class instance doesn't mater because in Objective-C, classes are also objects. Using dot notation on a class calls the parameterless method on that class.

Dot notation is described in the Objective-C Programming Language document.


In the "evil but it works" category, I've been known to use convenience constructors with the dot notation once in a while, such as NSMutableArray *myArray = NSMutableArray.array


The Underscore library further abuses this syntax by returning blocks from class methods, resulting in code like this:

NSArray *elements = Underscore.array(array)
    .flatten
    .uniq
    .unwrap;

To understand how this works, look at the definition of Underscore.array:

+ (USArrayWrapper *(^)(NSArray *))array
{
    return ^(NSArray *array) {
        return [USArrayWrapper wrap:array];
    };
}

So:

Underscore.array(array) 

...is equivalent to this:

NSArray *array = @[];
USArrayWrapper * (^arr)(NSArray *) = [Underscore array];
USArrayWrapper *result = arr(array);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号