To jest temat o nazwie wyższego rzędu Messaging w kakao, a opracowane przez wielu ludzi w sieci. Zacznij od numeru here i wypróbuj więcej. Dodają metodę kategorię do NSArray
tak, że można zrobić
NSArray*transformed=[[anArray map] stringByDeletingPathExtension];
Idea jest następująca:
[anArray map]
tworzy tymczasowy obiekt (słownie hom
)
hom
odbiera komunikat stringByDeletingPathExtension
hom
ponownie wysyła wiadomość do wszystkich elementów anArray
hom
zbiera wyniki i zwraca wynikową tablicę.
Jeśli chcesz po prostu szybkie przetwarzanie, chciałbym zdefiniować metodę Kategoria:
@interface NSArray (myTransformingAddition)
-(NSArray*)my_arrayByApplyingBlock:(id(^)(id))block;
@end
@implementation NSArray (myTransformingAddition)
-(NSArray*)my_arrayByApplyingBlock:(id(^)(id))block{
NSMutableArray*result=[NSMutableArray array];
for(id x in self){
[result addObject:block(x)];
}
return result;
}
@end
Następnie można zrobić
NSArray* transformed=[anArray my_arrayByApplyingBlock:^id(id x){return [x stringByDeletingPathExtension];}];
Uwaga konstrukt ^ return-type (arguments) { ...}
która tworzy blok. Zwracany typ można pominąć, a clang
jest całkiem sprytny, jeśli chodzi o odgadywanie, ale gcc
jest dość ścisły i musi zostać określony w pewnym momencie. (W tym przypadku, to domyślić z rachunku return
który ma [x stringBy...]
która zwraca NSString*
. Więc GCC zgaduje typ zwracanej bloku być NSString*
zamiast id
, który uważa, GCC jest niezgodna, co przychodzi błąd.)
W systemie OS X Leopard lub iOS 3 można używać funkcji PLBlocks do obsługi bloków. Moją osobistą subiektywną opinią jest to, że ludzie, którym zależy na nowym oprogramowaniu, zwykle uaktualniają się do najnowszego systemu operacyjnego, więc wsparcie najnowszego systemu operacyjnego powinno być w porządku; obsługa starszego systemu operacyjnego nie zwiększy liczby klientów o dwa ...
, KTÓRA POWIEDZIAŁA, istnieje już dobre środowisko open-source, które robi wszystko, co powiedziałem powyżej. Zobacz dyskusję here, a zwłaszcza FunctionalKit połączony tam.
Dodatek dodatkowy: w rzeczywistości łatwo jest zrealizować pseudokod [array transform:stringByDeletingPathExtension]
.
@interface NSArray (myTransformingAddition)
-(NSArray*)my_transformUsingSelector:(SEL)sel;
@end
@implementation NSArray (myTransformingAddition)
-(NSArray*)my_transformUsingSelector:(SEL)sel;{
NSMutableArray*result=[NSMutableArray array];
for(id x in self){
[result addObject:[x performSelector:sel withObject:nil]];
}
return result;
}
@end
Wtedy można go używać w następujący sposób:
NSArray*transformed=[array my_transformUsingSelector:@selector(stringByDeletingPathExtension)];
Jednak nie podoba mi się tak bardzo; aby móc korzystać z tej metody, musisz mieć już zdefiniowaną metodę na obiekcie w tablicy. Na przykład, jeśli NSString
nie ma operacji, którą chcesz wykonać jako metodę, co byś zrobił w tym przypadku? Trzeba najpierw dodać go do NSString
poprzez kategoriach:
@interface NSString (myHack)
-(NSString*)my_NiceTransformation;
@end
@implementation NSString (myHack)
-(NSString*)my_NiceTransformation{
... computes the return value from self ...
return something;
}
@end
Następnie można użyć
NSArray*transformed=[array my_transformUsingSelector:@selector(my_NiceTransformation)];
Ale to wydaje się być bardzo gadatliwy, bo trzeba zdefiniować metody w innych miejscach w pierwszej kolejności. Wolę dostarczanie co chcę działać bezpośrednio w miejscu połączenia, jak w
NSArray*transformed=[array my_arrayByApplyingBlock:^id(id x){
... computes the return value from x ...
return something;
}];
Wreszcie metod kategorii nigdy add które nie zaczynają się od przedrostka jak my_
czy cokolwiek innego. Na przykład w przyszłości Apple może dostarczyć fajną metodę o nazwie transform
, która robi dokładnie to, co chcesz. Ale jeśli masz już w tej kategorii metodę o nazwie transform
, doprowadzi to do niezdefiniowanego zachowania. W rzeczywistości może się zdarzyć, że istnieje prywatna metoda Apple już w klasie.
Biorąc pod uwagę wszystkie 'transform' naprawdę jest pętla nad elementami, nie jestem naprawdę widząc niewykwitność tego robić samemu ... –
chcesz zrobić to w miejscu lub stworzyć nową tablicę? Czy musisz również usunąć ścieżki do plików? Przykładowe dane (pokazujące początkowe elementy tablicy i wyniki, które mają być) będą pomocne. Najlepszą rzeczą przy pisaniu pytania jest dostarczenie szerokiej gamy informacji przy zachowaniu jej zwięzłości. – outis
@Nicholas: chodzi o wyższe poziomy abstrakcji i łatwość konserwacji. Kiedy możesz wyrazić swój zamiar na jednej linii i nie musisz pisać (lub kopiować/wklejać) tej samej pętli wiele razy, kod jest łatwiejszy do zrozumienia i utrzymania. Jeśli pojedyncza linia jest wystarczająco zaawansowana (a.k.a. zbyt sprytna dla przeciętnego programisty), to wolałbym też pętlę. – pesche