В таких языках, как C++
и C#
при создании содержимого, такого как std::vector
или C#
list
, вы явно объявляете тип контейнера при его создании:
C ++:
std::vector<MyObject>
C #:
List<MyObject> list = new List<MyObject>();
Глядя на код выше, я сразу знаю, что эти контейнеры могут содержать только объекты типа MyObject
, и компилятор будет жаловаться, если я попытаюсь добавить объект, который не относится к этому типу.
Поскольку Objective-C является динамическим языком, у нас нет привилегии компилятора, предупреждающего нас об этом (потому что это совершенно допустимая, но потенциально опасная вещь):
Objective-C:
NSDictionary *dict = [[NSDictionary alloc]init];
[dict setValue:[[SomeClass alloc]init] forKey:@"someClass"];
[dict setValue:[[NSMutableString alloc]init] forKey:@"mutableString"];
BOOL classIsSomeClass = [[dict objectForKey:@"someClass"] isKindOfClass:[SomeClass class]];
Вместо этого что-то вроде NSDictionary
или NSArray
будет хранить и принимать объекты любого типа, которые наследуются от NSObject
. Я нахожу это само по себе очень гибким, но на самом деле я не могу быть уверенным в типе объекта в контейнере, который я могу знать только по runtime
, тогда как по c++
или c#
я знаю это по compile time
и просто глядя код.
Должен ли я проверять содержимое контейнеров при добавлении, использовании и удалении объектов для классов контейнеров (NSArray
, NSSet
, NSDictionary
и т. Д.) Из Apple Foundation Framework ? Или это нормально при любых обстоятельствах, и проверка сильно ухудшит производительность?
NSDictionary *dict = [[NSDictionary alloc]init];
[dict objectForKey:@"someKey"]; // return nil?