Выделите любой изменяемый объект с неизменным классом или наоборот
Это может звучать довольно странно для некоторых людей... но я просто продолжал спрашивать об этом.. Очевидно, никто не хочет делать это... но просто чтобы прояснить концепцию, я хочу спросить. Обычно мы делаем это так:
NSString *myString=[[NSString alloc]init];
NSString *myString=[NSString string];
Насколько я понимаю, это дает указатель на объект NSString
класс, но что, если я сделаю это так:
NSString *myString=[[NSMutableString alloc]init];
NSString *myString=[NSMutableString string];
Если это произойдет, к какому классу на самом деле принадлежит "строка".. и, поскольку я инициализировал ее изменяемым классом, могу ли я отправлять сообщения класса NSMutableString в "myString", который является объектом класса NSString?? В любом случае, я могу знать, какова концепция этого... также, это может быть в случае массивов, словарей и даже многих других calsses.
2 ответа
Да. Тип вашего объекта будет тот, который используется методом alloc. Если вы разместили с NSMutableString, то ваш объект будет членом класса NSMutableString.
NSString *myString=[[NSMutableString alloc]init];
Что происходит, у вас есть указатель на выделенный объект с типом его родительского класса, поэтому компилятор не будет видеть методы NSMutableString и получит предупреждение, если вы попытаетесь вызвать их напрямую.
Но опять же, ваш объект все еще является членом класса NSMutableString, и он будет отвечать на сообщения класса NSMutableString.
Даже если вы объявили myString как указатель на NSString, вы можете выполнить этот тест, чтобы понять, о чем я говорю:
BOOL test = [myString isKindOfClass:[NSMutableString class]]; //this will hold true
Вы даже можете выполнить приведение к явному вызову метода.
NSString *myString=[[NSMutableString alloc]init];
[(NSMutableString*)myString someNSMutableStringSpecificMethod];
PS: это относится не только к изменяемым / неизменным объектам, но и ко всем классам специализации
Что происходит на второй линии, вы получаете NSMutableString
объект, но ссылка является NSString
, вы можете вызывать сообщения только на открытом интерфейсе ссылки, поэтому сообщения будут отправляться на ваш NSMutableString
объект, НО только интерфейс, представленный NSString
было бы видно.
Однако вы можете в любое время бросить его на NSMutableString
например:
[((NSMutableString *)myString) appendString:@"anotherString"] // This works because of the cast
[myString appendString:@"anotherString"] // Compiler complains because it does not find that method in NSString interface.
и отправлять сообщения, выставленные NSMutableString
интерфейс.