Условное выделение NSArray без получения ошибки от статического анализатора?

ДЛЯ СЛЕДУЮЩЕГО КОДА

 NSArray *colors = [[NSArray alloc]init];
if ([CONDITION]) {
    colors = @[
               [UIColor colorWithRed:240/255.f green:159/255.f blue:254/255.f alpha:1],
               [UIColor colorWithRed:255/255.f green:137/255.f blue:167/255.f alpha:1],
               [UIColor colorWithRed:126/255.f green:242/255.f blue:195/255.f alpha:1],
               [UIColor colorWithRed:119/255.f green:152/255.f blue:255/255.f alpha:1],
               [UIColor colorWithRed:240/255.f green:159/255.f blue:254/255.f alpha:1],
               ];
} else {
    colors = @[
               [UIColor colorWithRed:240/255.f green:159/255.f blue:254/255.f alpha:1],
               [UIColor colorWithRed:255/255.f green:137/255.f blue:167/255.f alpha:1],
               [UIColor colorWithRed:126/255.f green:242/255.f blue:195/255.f alpha:1],
               [UIColor colorWithRed:119/255.f green:152/255.f blue:255/255.f alpha:1],
               ];
}

Этот код выполняется отлично, но во время анализа памяти я получаю ошибку в статическом анализаторе «Dead Store» «Значение, сохраненное в« цветах »во время его инициализации, никогда не читается», я не уверен, как еще я могу выполнить этот код.


person Abhinav Singh    schedule 22.11.2013    source источник
comment
Объект, который вы выделяете в первой строке, теряется. Просто установите указатель на nil.   -  person Hot Licks    schedule 22.11.2013
comment
(Это классическая проблема непонимания разницы между указателем и объектом. Честно говоря, вам не следует кодировать на Objective-C, если вы не понимаете этой разницы.)   -  person Hot Licks    schedule 22.11.2013


Ответы (2)


Измените первую строку на

NSArray *colors;

Достаточно объявить переменную. Нет необходимости создавать пустой массив и устанавливать переменную в этот неиспользуемый экземпляр.

Пока переменная не будет установлена ​​в правильный массив (в условии), ее значение будет nil в ARC и не определено в ручном сохранении счетчика. Это не имеет отношения к вашему случаю, поскольку значение никогда не читается перед назначением.

Редактировать: Из комментария и другого ответа по-прежнему кажется, что люди сосредотачиваются на выделении неиспользуемого массива. Конечно, это избыточно, но компилятор предупреждает о том, что переменная присваивается, а затем никогда не читается до следующего присваивания. Если бы вы использовали переменную типа int, предупреждение было бы таким же.

person Nikolai Ruhe    schedule 22.11.2013
comment
Синтаксис @[...] уже является сокращением для выделения/инициализации массива. Итак, вы сначала инициируете, а затем повторно инициируете что-то еще. - person Cyrille; 22.11.2013
comment
И если вы не используете ARC, первый массив протечет. Анализатор будет орать по этому поводу. - person Hot Licks; 22.11.2013

Как уже упоминалось, нет необходимости alloc/init массива, в котором вы объявляете переменную.

Несколько причин:

Наиболее очевидным является то, что в строке

NSArray *colors = [[NSArray alloc]init]

вы создаете объект и присваиваете его переменной только для того, чтобы перезаписать его сразу после присваивания в обеих ветвях оператора if.

Каким бы ни было условие оператора if, ваш вновь созданный массив будет потерян.

С практической точки зрения, он будет иметь продолжительность жизни (максимум) несколько микросекунд, и никогда не будет использоваться для чего-либо полезного. Это то, что статический анализатор пытается вам сказать, когда он говорит: «Значение, сохраненное в 'colors' во время его инициализации, никогда не читается» — чтение значения переменной — это первый шаг к тому, чтобы сделать с ней что-то полезное. Так что, если вы никогда не прочитаете это снова, вы можете не назначать его.

Чуть более тонкая причина заключается в том, что простой NSArray является неизменяемым, а вызов alloc/init для неизменяемого класса коллекции просто создает пустую коллекцию, которую никогда нельзя заполнить чем-либо полезным.

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

person Monolo    schedule 22.11.2013
comment
Да, вообще следует считать, что любое использование [[NSArray alloc] init] является ошибкой, пока не доказано обратное. - person Hot Licks; 22.11.2013