無名メソッドを作成する【ダークサイドObjective-C】

無名メソッドとはいってもブロック構文のことではないですよ。

厳密には「引数付き無名メソッド」と言ったほうが正確かもしれません。

引数付き無名メソッド

Objective-Cは引数有りのメソッドに限り、メソッド名を省略することができます。 この仕様は実用性はともかく凄く面白いです。

こんな書き方ができます。

NSString *str = [@"abc" :@"def"];   // "abcdef"
NSString *ret = [[str :@"-"] :str]; // "abcdef-abcdef"

作り方はこうです。

@interface NSString (MaryCore)
- (NSString *):(NSString *)a;
@end

@implementation NSString (MaryCore)
- (NSString *):(NSString *)a {
   return [NSString stringWithFormat:@"%@%@", self, a];
}
@end

言語仕様的に不安がありますが、内部的には:という一文字のセレクターとして解釈されているため問題なく動いているようです。

SEL ape = NSSelectorFromString(@":");
NSString *ab = [@"a" performSelector:ape withObject:@"b"]; // "ab"

なお、無名メソッドはリファクタリング機能による名前の一括変換には対応していません。型破りなテクニックでもあるため、ダークサイ度は「★5つ」とします。

パラメーター省略テクニックとの合わせ技

ちなみに、以前紹介しましたが、Objective-Cはパラメータのラベル名を省略することも可能ですので、メソッド名とラベル名を省略する合わせ技も可能になります。

[@"a" :@"b" :@"c"]; // "abc"

- (NSString *):(NSString *)a :(NSString *)b {
   return [NSString stringWithFormat:@"%@%@%@", self, a, b];
}

NSArrayやNSNumberでjoin/add系のメソッドとして使用したり、 よく使うメソッドへのエイリアスとして利用したり、いろいろ妄想が広がりますね。

// あんなことや
NSArray *ary = [@[@"foo"] :@[@"bar"]]; // ["foo", "bar"]
// こんなことが、できてしまいます
NSNumber *sum = [@1 :@2 :@3 :@4]; // 10

むふふ。


俺「Obj-Cかわいいよ・・・Obj-C・・・」
Objective-C「これ以上近づいた場合は法的措置に踏み切ります」

広告