2015-10-19 2 views
1

Скажите, что у вас есть метод, который возвращает NSDictionary. Для создания словаря вам может понадобиться создать NSMutableDictionary. Есть ли необходимость или преимущество в возвращении неизменной копии словаря, а не просто возвращении изменяемого словаря?Нужно ли или необходимо преобразовать измененные NSObjects в неизменяемые, прежде чем возвращаться из методов?

например.

- (NSDictionary *)doSomethingAndReturnADictionary { 
    NSMutableDictionary * dic = [NSMutableDictionary new]; 
    // fill in dic 
    return dic; 
} 

или лучше сделать следующее:

- (NSDictionary *)doSomethingAndReturnADictionary { 
    NSMutableDictionary * dic = [NSMutableDictionary new]; 
    // fill in dic 
    return [NSDictionary dictionaryWithDictionary:dic]; 
} 

Я думаю, копируя словарь, особенно если это большой один, это пустая трата ресурсов. Я полагаю, что NSMutableDictionary занимает больше памяти, но я сомневаюсь, что есть большая разница. Метод может вернуть NSMutableDictionary, но если словарь не предназначен для изменения после его возвращения, зачем беспокоиться? Возвращаемый словарь - это NSMutableDictionary, но компилятор будет показывать его как NSDictionary.

Тот же вопрос относится к NSArray, NSString и т. Д. Мне не удалось найти аналогичный вопрос.

Любые лучшие практики/все, что нужно учитывать?

ответ

1

ИМО, это хорошая практика для возврата неизменяемого объекта, если ожидается неизменность.

Рассмотрим это:

NSString *stringExpectedToBeImmutable = [NSMutableString stringWithString:@"My immutable string."]; 

[((NSMutableString *) stringExpectedToBeImmutable) appendString:@" Really?"]; 

NSLog(@"%@", stringExpectedToBeImmutable); 

Кто-то может ожидать, что NSString передается в метод неизменен и сделать некоторые вычисления на основе этого предположения, то в середине вычисления строки меняется. Когда начинается вычисление, строка имеет длину 20 символов и внезапно она равна 28.

Это также является причиной того, что свойства типа NSString должны быть объявлены как copy.

Это, конечно, кромка края, но хорошо иллюстрирует проблему.

Вместо [NSDictionary dictionaryWithDictionary:dic] вы можете позвонить по телефону [dic copy]. Я думаю, copy - самый эффективный способ получить неизменяемую копию изменчивых объектов.

В заключении:

  • , если вы говорите, что вы возвращаете неизменный объект, вернуть непреложный
  • , если какой-либо метод или API ожидать неизменный объект, дать им непреложные
  • использовать copy получить непреложную версию изменяемые объекты
  • Я бы не боялся производительности накладных расходов. Преждевременная оптимизация - злая :)
1

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

Apple, по-видимому, по этой же совет: Возвращаемое значение [NSThread callStackSymbols] является NSArray, но если вы проверяете его во время выполнения, вы найдете это экземпляр NSMutableArray

+1

Есть некоторые конкретные исключения. Например, ['NSMutableCharacterSet' документы] (https://developer.apple.com/library/prerelease/mac/documentation/Cocoa/Reference/Foundation/Classes/NSMutableCharacterSet_Class/index.html), что он менее эффективен в использовании, чем 'NSCharacterSet' и рекомендует делать неизменяемую копию, как только вы ее модифицируете. –