2

だから私はこれをしたい:

switch (keyPath) {
    case @"refreshCount":
        //do stuff
    case @"timesLaunched":
       //do other stuff
}

ただし、スイッチの数量として使用できるのは整数のみであるようです。これを行う唯一の方法は、文字列を整数識別子に解析してから、switchステートメントを実行することですか?

このような:

nsinteger num = nil;

if (keyPath isEqual:@"refreshCount") {

num = 0

}

if (keyPath isEqual:@"timesLaunched") {

num = 1

}

頻繁に呼び出されるため、このコードをできるだけ速く最適化しようとしています。

ありがとう、

ニック

注:はい、KVOを使用しているので、「コールバック」で文字列を受信して​​います。

注2:最初にswitchステートメントを検討したのは、元のコードの実装は次のようなものでした。

if ([keyPath isEqual:@"refreshCount"] && ([[change valueForKey:@"new"] intValue] == 10)) { //  
NSLog(@"achievemnt hit inside");
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"title" message:@"Achievement Unlocked!" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:nil];
    [alert show];

異なるXX値を使用して、これらをすべて同じ方法で実行したいと思います。

if ([keyPath isEqual:@"refreshCount"] && ([[change valueForKey:@"new"] intValue] == 10)) {

//unlock small achievement

}
 if ([keyPath isEqual:@"refreshCount"] && ([[change valueForKey:@"new"] intValue] == 50))   {

//unlock bigger achievement

}   

//etc

これは私には非常に非効率に思えましたが、おそらく私は間違っています。

4

3 に答える 3

6

つまり、キャストステートメントが機能するには、isEqualToString:とにかく呼び出す必要があり、同じくらい遅くなりますが、おそらくあなたが思っているほど遅くはありません.

もちろん、最初の質問は、パフォーマンスを測定したか、コードがパフォーマンスの問題を引き起こしているという証拠があるかということです。

そうでない場合は、アプリを完成させてください。配送アプリは、常に開発中のアプリよりも優れています。

パフォーマンスの問題はないと思います。すべての文字列が実際@"refreshCount"にキー値の監視に関連するインライン文字列定数などである場合、それらすべてがアプリにコンパイルされた定数文字列である可能性が非常に高いため、比較は非常に高速になります。あなたが言及するたび"@refreshCount"に、実際には同じアドレスの同じ文字列です(非常に高速に比較されます)。

定量化可能なパフォーマンスの問題がある場合は、詳細を別の質問に投稿してください。誰かが具体的に答えることができます。現状では、推測以上のことを行うのに十分な構造的または定量的な情報はありません。

于 2010-05-25T17:40:53.960 に答える
4

列挙型を使用しないのはなぜですか?

typedef enum _KeyPath
{
     KeyPathNone,
     KeyPathRefreshCount,
     KeyPathTimesLaunched,
     KeyPathCount
} KeyPath;

比較する必要がある文字列を使用する必要がある場合isEqualToString:

NSString ドキュメントから:

Special Considerations
When you know both objects are strings, this method is a faster way to check equality than isEqual:.
于 2010-05-25T17:38:58.683 に答える
2

簡単な答えは、そもそも文字列を使用しないことです。それを除けば、文字列を整数 (NSNumber) 値を持つ辞書のキーにすることができます。または、文字列のハッシュを使用できます。

switch ( [keyPath myQuickHash] ) {
case kHashRefreshCount:
case kHashTimesLaunched:
}

いくつかの異なる文字列がある場合は、最初 (または最後) の 4 文字を文字列リテラルとして使用し、それをハッシュと見なすことができます。

switch ( [keyPath stringLiteral] ) {
case 'refr':
case 'time':
}

編集:

switch ステートメントは、基本的にコード スニペットのまばらな配列です。ハッシュ テーブルは、任意の値が与えられたスパース配列のインデックスを検索する手段です。既知の文字列入力のセットが与えられると、switch ステートメントはハッシュ テーブルのように動作できます。つまり、一定のルックアップ時間があります。既知の入力に対して衝突のないハッシュ アルゴリズムを選択するだけです。入力のセットが不明な場合、これはオプションではありませんが、この質問では、すべての入力が既知である可能性があります。

これは、独自のハッシュ アルゴリズムを実装する必要があるため、Apple がハッシュ アルゴリズムを実装する方法とはまったく関係ありません。選択されたアルゴリズムは、文字列の長さと文字を合計するのと同じくらい簡単かもしれません。

于 2010-05-25T17:40:00.577 に答える