2011-07-20 9 views
4

プリプロセッサを乱用しようとしている可能性があります。私は心に留めていることが可能であるかどうかを見たいと思う。Cプリプロセッサで@propertyの実装を生成する(プリプロセッサの文字を大文字にする)

私のクラスは、すべてが同じボディを持つ@propertiesを持っています。これらのボディをプリプロセッサマクロで生成したいと思います。例えば:

- (float) accelerometerSensitivity { 
    return [dict floatForSelector:_cmd or:1]; 
} 
- (void) setAccelerometerSensitivity:(float) n { 
    [dict setFloat:n forSelector:_cmd]; 
    [dict writeToFile:[self globalDataFilename] atomically:YES]; 
} 

- (float) returnSpringTension { 
    return [dict floatForSelector:_cmd or:0]; 
} 
- (void) setReturnSpringTension:(float) n { 
    [dict setFloat:n forSelector:_cmd]; 
    [dict writeToFile:[self globalDataFilename] atomically:YES]; 
} 
// set*ForSelector methods are in a category on NSMutableDictionary and depend on a function that translates selectors into strings: 
// NSString* keyFromSelector(SEL selector); 

アイデアはなく辞書へのキーとして文字列リテラル(または文字列定数)を用いる、Iは、セレクタ名の文字列を導出することです。このようにして、キーのスペルがプロパティ名と一致し、基本的に辞書キーのコンパイル時検証の利点が得られると確信しています。

私がしたいことは、SELECTOR_PROPERY(accelerometerSensitivity)のようなもので、ゲッターとセッターに広げてください。プリプロセッサマクロとして実装する上での主な難点は、プロパティ名からセッター名を生成することです。私はプロパティ名の最初の文字を大文字にする必要があり、プリプロセッサでこれをどうするかわかりません。

答えて

5

Nope, you can't do that.

しかし、理論的にはあなたがこれを定義することができるようにあなたは、識別子を組み合わせることができます:それはややklugeyだが、それは代替よりも簡潔だ

MACRO(A,a,ccelerometerSensitivity) 

+0

ええ、それは私が考えているフォールバックです。 CPPが私が望むような操作を行う表現力を持っていないことを確認していただきありがとうございます。 – iter

0

は、ここで私はそれを行うだろう方法は次のとおりです。

#define MACRO(_a) { \ 
const char *name = #_a; \ 
NSString *getterName = [NSString stringWithUTF8String:name]; \ 
NSString *setterName = [NSString stringWithFormat:@"set%c%s:", toupper(name[0]), (name+1)]; \ 
NSLog(@"getter name: %@", getterName); \ 
NSLog(@"setter name: %@", setterName); \ 
} 

基本的に、あなたが最初の文字を大文字に簡単なC関数を使用し、その後、マクロパラメータを文字列化し、最初の文字の後にすべてを取得するためにオフセットを使用します。

2011-07-19 21:21:24.798 EmptyFoundation[16016:903] getter name: foo 
2011-07-19 21:21:24.800 EmptyFoundation[16016:903] setter name: setFoo: 
2011-07-19 21:21:24.801 EmptyFoundation[16016:903] getter name: bar 
2011-07-19 21:21:24.802 EmptyFoundation[16016:903] setter name: setBar: 

しかし、これらは文字列です:

MACRO(foo); 
MACRO(bar); 

それは、このログに記録します。

は今、あなたはこれを行うとき。メソッド名としては使用できません。ごめんなさい。 。:(

0

実際に、あなたはおそらく本当には、建築的な理由のために純粋にこれを行うにはしたくない

あなたはおそらく、あなたの場合ほうが良いでしょう:

  • はの概念を分離しますの設定状態から持続状態。小さな変更を1回行うごとにI/Oの原因となることはひどく非効率的であり、問​​題の可能性を秘めたモードです。値はUIを継続的に追跡しますか? ...あなたは実際にダイヤル/スライダが指の下で追跡されるたびに、ディスクI/Oを必要としません!

  • すべての@propertiesに対して@synthesizeを使用し、ivarsを宣言することさえしません。正確なセッター/ゲッターを生成するツールの能力を活用してください。

  • NSUserDefaultsのコードは、あなたが再発明したように非常によく見えますか?どんなユーザーの好みのためにもNSUserDefaultsを使用してください。

+0

私の質問は私が何をしたいのか尋ねません。それは私がしたいことを意味します。 --- 私が生成したいコードは、すでにソースにあるコードであり、それは私の満足のために実行されます。私はコピー貼り付けの代わりにそれを生成する方法を尋ねています。 --- この例では、ディクショナリを除いてイヤリングはありません。これは、ユーザー設定を維持する準備ができているときに行くクラスです。私は状態と永続性を分離するというあなたの概念を支持しています。これが永続性の部分です。 --- NSUserDefaultsは答えではありません。私のUIは洗練されており、設定の一角ではなく、アプリ内での生活を望んでいます。 – iter

+3

NSUserDefaultsはあなたのアプリから完全に使用可能です*。 *設定に行く必要はありません。それがユーザーのデフォルトの全体のポイントです。ユーザーのデフォルト設定は、一般に、状態が変わるたびにディスクのスパムを防ぎます。 – bbum

+0

ありがとうございます。それは、あなたが私のアプリで使えるものを知っていることを私にフラットにします。私はNSUserDefaultsの経験は限られていますが、私が使っているところでは、設定アプリにUI要素が作成されています(これはすべてiOS上にあります)。いずれにしても、NSUserDefaultsは文字列キーを使用して値を検索しますが、文字列リテラル(またはリテラルに解決される定数)をキーとして使用しないようにすることが重要です。私の経験では、アプリケーションのこれらの文字列キーが12個以上あると、スペルミスは迷惑になります。 NSUserDefaultsを使用すると、マクロの本体だけが変更されます。 – iter

関連する問題