Выделите любой изменяемый объект с неизменным классом или наоборот

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

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 интерфейс.

Другие вопросы по тегам