в iOS 5 метод, возвращающий NSString, иногда возвращает мусор - PullRequest
1 голос
/ 07 ноября 2011

У меня есть приложение, которое отлично работает в iOS 4, но происходит сбой при прокрутке UITableView, когда тот же самый точный код компилируется с использованием iOS5 и XCode 4.2. Оскорбительный код ниже:

    - (NSString *)getDefaultIconName {
        NSInteger value = [self.iconId characterAtIndex:0] % 4;
        NSString *returnValue = nil;

        switch (value) {
            case 0:
                returnValue = @"default_icon_1";
                break;
            case 1:          
                returnValue = @"default_icon_2";
                break;
            case 2:
                returnValue = @"default_icon_3";
                break;
            case 3:
            default:
                returnValue = @"default_icon_4";
                break;
        }

        return returnValue;
    }

Этот метод вызывается из подкласса UITableViewCell, который создается или повторно используется в вызове cellForRowAtIndexPath. Когда таблица создана и ячейки показаны, этот вызов возвращает правильную строку. Когда я прокручиваю таблицу вниз, этот вызов возвращает недопустимую ссылку, что приводит к сбою моей попытки сохранить строку в другом классе с EXEC_BAD_ACCESS. В отладчике я вижу, что UITableViewCell существует правильно, и все значения установлены правильно, кроме возвращаемого значения для этого вызова, которое говорит Invalid CFStringRef.

Странно, если я помещаю инструкцию NSLog, распечатывающую returnValue перед возвратом, он не падает. То же самое верно, если я поставлю проверку, чтобы проверить, является ли returnValue isKindOfClass: [NSString class] перед его возвратом.

Третье, что я заметил, это то, что, если я компилирую с отключенной оптимизацией кода, он также не падает.

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

edit: К сожалению, returnValue отсутствует * была опечатка.

Ответы [ 4 ]

2 голосов
/ 07 ноября 2011

Добавьте * к returnValue, когда вы его объявляете. Прямо сейчас это не указатель.

1 голос
/ 07 ноября 2011

Нет ничего явно плохого в коде, который вы вставили, так что поищите проблемы (повреждение памяти, чрезмерно освобожденные объекты) в другом месте.

Кроме того, вместо оператора switch () вы можете индексировать в массив возвращаемых значений:

NSInteger value = [self.iconId characterAtIndex:0] % 4;
NSString *icons[4] = {@"default_icon_1",
   @"default_icon_2",
   @"default_icon_3",
   @"default_icon_4"};

return icons[value];
0 голосов
/ 07 ноября 2011

Это может быть потому, что в случае 3 вы возвращаете returnValue, когда он равен нулю?Если это так, установите returnValue в значение по умолчанию.

Также убедитесь, что вы не делите на ноль.

0 голосов
/ 07 ноября 2011

switch case не не работает с объектами Objective-C. Вместо этого используйте if-else.

...