ココア高次メッセージングと呼ばれる話題だし、ウェブ上の多くの人々によって開発されました。 hereから始めて、グーグルグーグルを試してみてください。
[anArray map]
は一時オブジェクト(たとえばhom
)
hom
がメッセージstringByDeletingPathExtension
を受け作成します。彼らはあなたが
NSArray*transformed=[[anArray map] stringByDeletingPathExtension];
を行うことができるように、次のような考え方があるNSArray
にカテゴリメソッドを追加します
hom
は、すべての要素にメッセージを再送信します。anArray
hom
は結果を収集し、結果の配列を返します。
あなただけの迅速な変換したい場合、私は、カテゴリメソッドを定義します
@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
次にあなたが
NSArray* transformed=[anArray my_arrayByApplyingBlock:^id(id x){return [x stringByDeletingPathExtension];}];
ノートにブロックを作成し、構造^ return-type (arguments) { ...}
を行うことができます。戻り値の型は省略することができ、clang
はそれを推測する上でかなりスマートですが、gcc
はそれについてかなり厳密で、いつか指定する必要があります。 (この場合には、NSString*
を返す[x stringBy...]
を持ってreturn
の文から推測だ。だから、GCCは、このようにエラーが出たとき、GCCは互換性がないと考える代わりにid
のNSString*
、するブロックの戻り値の型を推測します。)
OS X LeopardまたはiOS 3では、PLBlocksを使用してブロックをサポートできます。私の個人的な主観は、新しいソフトウェアを気にする人は、通常は最新のOSにアップグレードするので、最新のOSをサポートすることは問題ないはずです。古いOSをサポートしても2倍にはならないでしょう。
THAT SAIDは、上記のすべてのことを行う素晴らしいオープンソースフレームワークです。詳しくはhere、特にFunctionalKitのリンクを参照してください。
さらに追加:擬似コード[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
次のように次に、あなたがそれを使用することができます。
NSArray*transformed=[array my_transformUsingSelector:@selector(stringByDeletingPathExtension)];
を、私はそれはあまり好きではないが。このメソッドを使用するには、配列内のオブジェクトに対してすでにメソッドが定義されている必要があります。たとえば、NSString
にメソッドとして実行したい操作がない場合、この場合はどうしますか?あなたは最初のカテゴリを経由してNSString
に追加する必要があります。
@interface NSString (myHack)
-(NSString*)my_NiceTransformation;
@end
@implementation NSString (myHack)
-(NSString*)my_NiceTransformation{
... computes the return value from self ...
return something;
}
@end
次にあなたが
NSArray*transformed=[array my_transformUsingSelector:@selector(my_NiceTransformation)];
を使用することができます。しかし、あなたが最初に他の場所でメソッドを定義する必要があるため、それは、非常に冗長になりがち。私は
NSArray*transformed=[array my_arrayByApplyingBlock:^id(id x){
... computes the return value from x ...
return something;
}];
に最後に、がmy_
か何かのような接頭辞で始まっていないカテゴリのメソッドを追加したことがないよう、呼び出しサイトで直接操作したいものを提供好みます。たとえば、将来的にAppleはtransform
と呼ばれる素晴らしい方法を提供するかもしれません。しかし、すでにカテゴリにtransform
というメソッドがあると、未定義の動作につながります。実際には、すでにクラス内にAppleのプライベートメソッドがあることが起こる可能性があります。
は要素をループで、私は本当に自分自身そうすることのぎこちなさを見ていないよ... –
あなたがしたいですかインプレースで行うか、新しいアレイを作成するか?また、ファイルへのパスを削除する必要がありますか?サンプルデータ(初期配列要素を示し、結果をどのようにしたいか)が役立ちます。質問を書く際には、情報を幅広く提供し、簡潔にしておくことが最善の方法です。 – outis
@Nicholas:抽象度が高く、保守性が高いです。 1つの行にあなたの意図を表すことができ、同じループを何度も書く必要がない(またはコピー/ペーストする)と、コードを理解して維持するのがより簡単になります。 1行が十分に進んでいれば(普通のプログラマーにとってはあまりにも賢明です)、私はループすることも好きです。 – pesche