20 Stimmen

Objective-C Punktnotation mit Klassenmethoden?

Beachten Sie, dass ich mich speziell auf die Tatsache beziehe, dass die Punktnotation bei Klassenmethoden und nicht bei Instanzmethoden verwendet wird.

Aus Neugierde wollte ich sehen, was passieren würde, wenn ich versuchen würde, die Objective-C Punktnotation mit einer Klassenmethode zu verwenden. Mein Experiment sah folgendermaßen aus:

#import <Foundation/Foundation.h>

static int _value = 8;

@interface Test : NSObject

+ (int) value;
+ (void) setValue:(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;
}

Ich war überrascht zu sehen, dass dies kompiliert wurde, geschweige denn mit einem, wie ich annehme, korrekten Verhalten ausgeführt wurde. Ist dies irgendwo dokumentiert, oder nur ein Zufall des Compilers?

Ich habe mit GCC auf Mac OS X 10.6 kompiliert:

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

0 Stimmen

Und ich frage mich, warum Xcode nicht automatisch vervollständigen wenn die Punktsyntax für Klassenmethoden verwendet wird? Wenn es wirklich ein syntaktischer Zucker ist, z. B. foo.prop bedeutet rein rechnerisch [foo prop] dann sollte Xcode nicht zwischen Klassenmethoden und Instanzmethoden unterscheiden.

33voto

Barry Wark Punkte 106328

Dies ist ein korrektes Verhalten. foo.method ist syntaktischer Zucker für [foo method] -eine direkte Umwandlung mit identischer Semantik. Ähnlich foo.prop = bar ist syntaktischer Zucker für [foo setProp:bar] , wiederum mit identischer Semantik. Diese Transformation ist im Compiler implementiert. So können Sie kann die Punktnotation verwenden, um Methoden mit 0 Parametern aufzurufen, wie in foo.doSomething anstelle von [foo doSomething] . Natürlich, wenn Sie dies tun, sind Sie böse .

Die Tatsache, dass der Aufrufer eine Klasseninstanz ist, spielt keine Rolle, da in Objective-C Klassen auch Objekte sind. Die Verwendung der Punktnotation für eine Klasse ruft die parameterlose Methode für diese Klasse auf.

Die Punktschreibweise wird im Abschnitt Objective-C Programmiersprache Dokument.

12voto

NSResponder Punkte 16747

In der Kategorie "böse, aber es funktioniert" bin ich dafür bekannt, hin und wieder Komfortkonstruktoren mit der Punktnotation zu verwenden, wie z. B. NSMutableArray *myArray = NSMutableArray.array

0voto

Wayne Punkte 58002

En Unterstrich Bibliothek missbraucht diese Syntax weiter, indem sie Blöcke von Klassenmethoden zurückgibt, was zu Code wie diesem führt:

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

Um zu verstehen, wie das funktioniert, sehen Sie sich die Definition von Underscore.array :

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

Also:

Underscore.array(array) 

...ist gleichbedeutend mit diesem:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X