2010-05-25 1 views
2

Так что я хотел бы сделать это:iPhone OS: создание коммутатора оператора, который использует строковые литералы в качестве компараторов вместо целых

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 

} 

Я пытаюсь оптимизировать этот код, чтобы быть как можно быстрее, потому что его будет вызываться довольно часто.

спасибо,

Ник

Примечание: «обратный вызов» Да, я использую КВО, поэтому я ПОЛУЧАТЬ строку в

Примечание # 2: Так что заставило меня сначала рассмотреть заявление переключателя мое первоначальное внедрение кода было так:

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 

Это просто показалось мне очень неэффективным, но, возможно, я ошибаюсь.

ответ

6

То есть, для выполнения инструкции по исполнению, просто нужно было бы позвонить isEqualToString: в любом случае и будет таким же медленным, но, вероятно, не так близко, как вы думаете.

Первый вопрос, конечно, - У вас есть оценка производительности, и есть ли у вас доказательства того, что код вызывает проблему с производительностью?

Если нет, пойдите и закончите свое приложение. Приложение для доставки всегда превосходит приложение, все еще находящееся в разработке!

Готов поспорить, у вас нет проблемы с производительностью; если все ваши строки действительно являются строковыми строковыми константами - @"refreshCount" и т. п. - связанные с наблюдением за ключевыми значениями, то вполне вероятно, что все они являются постоянными строками, скомпилированными в приложение, и, таким образом, сравнение будет очень быстрым потому что каждый раз, когда вы упоминаете "@refreshCount", это действительно одна и та же строка с тем же адресом (которая очень быстро сравнивается).

Если у вас есть количественная проблема с производительностью, отправьте подробности в другом вопросе, и кто-то может ответить конкретно. Как бы то ни было, не хватает архитектурной или количественной информации, чтобы делать что-то большее, чем спекулировать.

+0

вы правы Я havent закодировал его, чтобы посмотреть, есть ли проблема, я просто сел и начал писать оператор switch, когда я хотел полностью внедрить метод, потому что я думал, что это будет намного эффективнее. Кстати: «Приложение для доставки всегда превосходит приложение, все еще находящееся в разработке!» это превосходно! Спасибо за это. Я добавляю еще одну заметку о моей первоначальной реализации, которая заставила меня подвергнуть сомнению эффективность в первую очередь. – nickthedude

+0

Добро пожаловать. Это хороший вопрос по нескольким причинам; строковые операции могут убить производительность, и в реализации постоянной последовательности реализована более тонкая реализация, чем можно было бы себе представить. – bbum

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:. 
+2

Очень вероятно, что он использует KVO или KVC и, таким образом, нуждается в путях как NSStrings. – bbum

+0

Да, я использую KVO, поэтому я возвращаю строку обратно, см. Добавленное примечание в вопросе. – nickthedude

+0

В этом случае используйте метод isEqualToString: 'и избегайте условных условий группы, поскольку он будет оценивать первую часть условного много раз. Вместо этого используйте вложенный условный. Если большое достижение может быть достигнуто только после небольшого, просто сделайте свое достижение, предоставляющее логику, отражать этот факт. – jessecurry

2

Короткий ответ не использовать строки в первую очередь. Если это не так, вы можете иметь строки в словарях с целыми (NSNumber) значениями. Или вы можете использовать хэши строк.

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

Если есть только несколько отдельных строк, вы можете использовать первые (или последние) 4-х символы в виде строки буквальной и считаете, что хэш.

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

Edit:

заявление переключатель, по существу, разреженный массив фрагментов кода. Хэш-таблица - это средство поиска индекса в разреженном массиве с учетом произвольного значения. Учитывая известный набор строковых вводов, оператор switch может работать как хэш-таблица, то есть иметь постоянное время поиска. Все, что вам нужно сделать, это выбрать алгоритм хеширования без столкновений для известных входов. Если набор входов неизвестен, это не вариант, но в этом вопросе возможно, что все входы известны.

Это абсолютно не имеет никакого отношения к тому, как Apple реализует свой алгоритм хэширования, потому что вы должны реализовать свой собственный алгоритм хеширования. Выбранный алгоритм, вероятно, может быть таким же простым, как сложение длины и букв в строке.

+1

Возможно, вы не захотите использовать хэши, так как очень небольшой, но ненулевой шанс столкновения может вызвать появление нечетных ошибок. «Enum», вероятно, более чистый и безопасный. –

+0

Хеши медленные. Очень очень медленно. Если мы говорим, например, 5 разных ключей, и все они являются постоянными NSStrings, прямое каскадное 'if (... isEqualToString: ...)' тесты, скорее всего, будут быстрее. – bbum

+0

Сравнение '-hash' с константой не будет работать. «Хэш» объекта остается постоянным во время выполнения. Использование операции подстроки может быть быстрее, а может и нет - зависит от набора строк. – bbum

 Смежные вопросы

  • Нет связанных вопросов^_^