Heute habe ich mit Objective-C Blöcke experimentierte so dass ich dachte, dass ich klug wäre, und fügen Sie ein paar funktionalen Stil Sammelmethoden NSArray, die ich in anderen Sprachen gesehen habe:mit Objective-C-Blöcke
@interface NSArray (FunWithBlocks)
- (NSArray *)collect:(id (^)(id obj))block;
- (NSArray *)select:(BOOL (^)(id obj))block;
- (NSArray *)flattenedArray;
@end
Die Methode collect: nimmt einen Block, der für jedes Element im Array aufgerufen wird und erwartet, dass die Ergebnisse einer Operation zurückgegeben werden, die dieses Element verwendet. Das Ergebnis ist die Sammlung all dieser Ergebnisse. (Wenn der Block null zurückgibt, wird der Ergebnismenge nichts hinzugefügt.)
Die select: -Methode gibt ein neues Array mit nur den Elementen aus dem Original zurück, das zurückgegeben wurde, wenn es als Argument an den Block übergeben wurde JA.
Und schließlich, die flattenedArray-Methode iteriert über die Elemente des Arrays. Wenn ein Element ein Array ist, ruft es flatterndArray rekursiv darauf auf und fügt die Ergebnisse zur Ergebnismenge hinzu. Wenn das Element kein Array ist, fügt es das Element zur Ergebnismenge hinzu. Die Ergebnismenge wird zurückgegeben, wenn alles fertig ist.
Jetzt, wo ich eine Infrastruktur hatte, brauchte ich einen Testfall. Ich beschloss, alle Paketdateien in den Anwendungsverzeichnissen des Systems zu finden. Dies ist, was ich mit kam:
Ja - das ist alles eine Zeile und es ist schrecklich. Ich versuchte ein paar Ansätze, Zeilenumbrüche und Einrückungen hinzuzufügen, um zu versuchen, es zu bereinigen, aber es fühlt sich immer noch so an, als ob der tatsächliche Algorithmus in all dem Rauschen verloren gegangen wäre. Ich weiß nicht, ob es nur eine Syntax-Sache oder meine relative In-Erfahrung mit der Verwendung eines funktionalen Stils ist, aber das ist das Problem.
Zum Vergleich habe ich beschlossen, es „auf die altmodische Art und Weise“ zu tun und nur Loops verwenden:
NSMutableArray *packagePaths = [NSMutableArray new];
for (NSString *searchPath in NSSearchPathForDirectoriesInDomains(NSAllApplicationsDirectory, NSAllDomainsMask, YES)) {
for (NSString *file in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:searchPath error:nil]) {
NSString *packagePath = [searchPath stringByAppendingPathComponent:file];
if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:packagePath]) {
[packagePaths addObject:packagePath];
}
}
}
IMO diese Version war einfacher zu schreiben und ist besser lesbar zu booten.
Ich nehme an, es ist möglich, dass dies ein schlechtes Beispiel war, aber es scheint eine legitime Möglichkeit zu sein, Blöcke für mich zu verwenden. (Bin ich falsch?) Fehle ich etwas über das Schreiben oder Strukturieren von Objective-C-Code mit Blöcken, die dies aufklären und es klarer machen würden (oder auch nur so klar wie) die geloopte Version?
Nizza Lösung, obwohl ich bin kein großer Fan von Neudefinition 'paths' mehrmals. Ich würde wahrscheinlich am Ende mehrere Werte basierend auf ihrem Inhalt benennen und am Ende mit einem namens "Pfade" enden. Nur meine zwei Cent. –
UIView-Animation verwendet 2 Blöcke. –
Er sagte Muster nicht Kanon. Diese Methoden, die mehrere Blöcke verwenden, haben alle Blöcke als letzte Parameter. Darüber hinaus erschienen diese APIs in iOS 4, das lange nach diesem Post war. – logancautrell