Ich habe keine Ahnung, ob das, was ich zu tun versuche, möglich ist oder nicht. Ich habe keine Erfahrung mit Blöcken, nur ein paar Tutorials gelesen, und wirklich wie die Idee. Meine Klasse AppointmentView.h (und m) ist eine Erweiterung eines ViewControllers. Sie enthält ein paar Eigenschaften, die Mitglieder einer anderen Klasse Appointment sind, die wiederum ein paar NSArrays hat. Um einen gruppierten Tableview zu erstellen, überprüfe ich die Werte der Arrays und kopiere dann die entsprechenden Werte, die angezeigt werden sollen (nichts allzu Ausgefallenes oder Kompliziertes). Normalerweise würde ich mit if-else-Anweisungen zu gehen, und die Kontrolle entsprechend, aber nach dem Blick auf Blöcke, es hat mich denken, wenn die folgenden machbar ist:
[self setOutcomes: [[NSArray alloc] initWithObjects:
^{ return [myAppointment.CANCELED isEqualToString:@"NO"] == YES ?
[[NSString alloc] initWithString:@"Not Cancelled"] :
[[NSString alloc] initWithString:@"Cancelled"]; },
^{ return [myAppointment.CANCELED isEqualToString:@"NO"] == YES ?
[[NSString alloc] initWithString:@"No Cancellation reason"] :
[[NSString alloc] initWithString:myAppointment.CANCREASON]; },
^{ return [myAppointment EVENTS].length > 0 ?
[[NSString alloc] initWithString:myAppointment.EVENTS] :
[[NSString alloc] initWithString:@"No Events"]; },
^{ return [myAppointment SUMMARY].length > 0 ?
[[NSString alloc] initWithString:myAppointment.SUMMARY] :
[[NSString alloc] initWithString:@"No Summary"]; },
nil]];
Dieser Code lässt sich gut kompilieren, stürzt aber bei der Ausführung ab. Meines Erachtens ist das falsch, weil ich die Aufzählung anweise, jedes Mal ein Stück Code auszuführen. Das ist also nicht das, was ich will. Dann habe ich das Folgende versucht:
[self setOutcomes: [[NSArray alloc] initWithObjects:
[[NSString alloc] initWithString: (NSString *) ^(void){
return [myAppointment.CANCELED isEqualToString:@"NO"] == YES ?
@"Not Cancelled" : @"Cancelled"; }],
[[NSString alloc] initWithString: (NSString *) ^(void){
return [myAppointment.CANCELED isEqualToString:@"NO"] == YES ?
@"No Cancellation reason" : myAppointment.CANCREASON; }],
[[NSString alloc] initWithString: (NSString *) ^(void){
return [myAppointment.EVENTS isEqualToString:@""] == YES ?
myAppointment.EVENTS : @"No Events"; }],
[[NSString alloc] initWithString: (NSString *) ^(void){
return [myAppointment.SUMMARY isEqualToString:@""] == YES ?
myAppointment.SUMMARY : @"No Summary"; }],
nil]];
Dieser lässt sich zwar gut kompilieren, stürzt aber mit dem folgenden Fehler ab:
-[ NSMallocBlock length]: nicht erkannter Selektor an Instanz 0x6bd68f0 gesendet
Ich habe auch versucht, eine generische Methode zu definieren, die ich verwenden könnte, aber auch das hat nicht geholfen. Ich frage mich also, ob das möglich ist. Ich weiß, dass ich für dieses Stück Code einfach ein if-else verwenden könnte (wie ich es normalerweise tun würde) und damit fertig wäre, aber unter anderen Umständen wäre eine solche dynamische Codegenerierungsoption äußerst nützlich.
Ich habe das Gefühl, dass entweder NSString nicht weiß, wie dies zu behandeln, und ich sollte daher erweitern es mit einer Optionen lässt sagen
initWithBlock:
Oder ich übersehe hier etwas anderes. Oder es ist vielleicht einfach nicht möglich.... (?)
PS: Ich habe soeben die Methode enumerateUsingBlock: von NSArray gesehen, aber ich bin mir nicht sicher, ob dies in diesem Fall meinem Zweck dienen würde, da sich jeder Eintrag im Array völlig von den anderen unterscheidet und ein bestimmter Block nicht den Kriterien entsprechen würde.