2016-04-15 2 views
0

Ich versuche, so etwas zu tun:Obj-C Wie eine Eigenschaft auf alle Elemente eines Arrays setzen

[array makeObjectsPerformSelector:@selector(setFoo:) withObject:[NSNumber numberWithBool:YES]]; 

wo foo eine öffentliche Eigenschaft ist (Typ BOOL) der Klasse der Elemente von Array. Dies funktioniert jedoch nicht, und ich denke, es hat damit zu tun, wie ich das Argument übergebe, weil es gut funktioniert, wenn ich das Array durchlaufen und [array[i] setFoo:YES] für jedes Element des Arrays aufrufen. Ich habe auch versucht, @YES und @"YES" zu übergeben.

+1

Die Methode 'setFoo:' benötigt ein 'BOOL'-Argument, aber Sie stellen eine 'NSNummer' bereit. Du kannst es nicht so machen. –

+0

Also, was ist der richtige Weg? –

Antwort

4

Dieses:

@interface Blarg:NSObject 
@property BOOL flag; 
@end 
@implementation Blarg 
@end 

int main(int argc, const char * argv[]) { 
    @autoreleasepool { 
     NSArray *a = @[[Blarg new], [Blarg new], [Blarg new]]; 
     NSLog(@"Start %@", [a valueForKey:@"flag"]); 
     [a setValue:@YES forKey:@"flag"]; 
     NSLog(@"Yes %@", [a valueForKey:@"flag"]); 
     [a setValue:@NO forKey:@"flag"]; 
     NSLog(@"No %@", [a valueForKey:@"flag"]); 

    } 
    return 0; 
} 

spuckt diese:

2016-04-14 23:28:00.648 dfjkdf[767:101069] Start (
    0, 
    0, 
    0 
) 
2016-04-14 23:28:00.650 dfjkdf[767:101069] Yes (
    1, 
    1, 
    1 
) 
2016-04-14 23:28:00.650 dfjkdf[767:101069] No (
    0, 
    0, 
    0 
) 

Ist es richtig? Irgendwie. Im Allgemeinen ist dies nicht wirklich ein Muster, das Sie verwenden sollten.

Du bist besser dran, etwas zu tun wie:

[a enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 
     Blarg *b = obj; 
     b.flag = YES; 
    }]; 

Oder besser mit einem modernen Compiler:

[a enumerateObjectsUsingBlock:^(Blarg * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 
     obj.flag = YES; 
    }]; 

Es ist ein paar zusätzliche Zeilen Code, aber es ist pedantisch Typ Korrekt und damit der Compiler wird schreien, wenn der Code in der Zukunft ändert, um es zu brechen. Meta-Programmierung hemmt die Fähigkeit des Compilers, Ihnen zu helfen.

+3

Die Enumeration kann noch einfacher sein, wenn Sie den Parameter 'obj' mit einem Typ 'Blarg' anstelle von 'id' deklarieren. Dann tun Sie einfach 'obj.flag = YES;'. – rmaddy

+0

@rpaddy Danke! Ich vergesse immer, dass du das jetzt tun kannst ... als wir zum ersten Mal Blöcke erstellt haben, war der Compiler dazu nicht in der Lage. :) – bbum

Verwandte Themen