Как вы объявляете экземпляр класса в Objective C? - PullRequest
0 голосов
/ 23 апреля 2011

Давайте представим, что у меня есть фракция класс. Итак, правильный способ создать его экземпляр:

Fraction *myFraction;
or
myFraction = Fraction;
or
myFraction = [Fraction new];

или что-то еще?

В книге я изучаю правильную книгу первой, но она кажется мне неразумной. Почему мы должны создать указатель для этого? Почему бы нам не сделать настоящий экземпляр?

Это первое выражение означает - дай мне указатель на новый экземпляр класса Fraction, не так ли?

Ответы [ 3 ]

4 голосов
/ 23 апреля 2011

Первый объявляет переменную с именем myFraction типа Fraction *, но ничего не создает и не инициализирует myFraction.Второй не действителен.Третий создает новый Fraction и назначает его ранее объявленной переменной с именем myFraction.Часто в Objective-C вы объявляете и инициализируете переменную в одном выражении:

Fraction *myFraction = [[Fraction alloc] init];

Что касается использования new или alloc, за которым следует init, это в значительной степени вопросвкуса.

Переменные для хранения объектов частично являются указателями, поскольку Objective-C унаследовал семантику C call-by-value call-by-value.Когда одна переменная назначается другой (например, при передаче ее функции), значение будет скопировано.В лучшем случае это неэффективно для неизменных объектов.В худшем случае это приводит к некорректному поведению.Указатели - это способ обойти семантику вызова по значению и копирование при назначении: значение переменной с типом указателя является просто указателем.Его можно скопировать, не касаясь целевого объекта.Стоимость для этого вам нужна некоторая форма управления памятью .

3 голосов
/ 23 апреля 2011

Было бы неплохо прочитать «Язык программирования Си» Кернихана и Ритчи, чтобы вы могли понять, как объявляются переменные.

Существует два режима выделения в C и Obj-C и C ++: ручной и автоматический .

Целые числа, числа с плавающей запятой и символы и т. Д. Обычно объявляются автоматически. Они создаются, когда объявление проходит (т. Е. int i ), и удаляются, когда исчезает область, в которой они были созданы, т. Е. При выходе из блока, в котором они были объявлены. Их называют автоматика . (также возможно объявить их «статическими», но для целей этого обсуждения относительно распределения они одинаковы)

Объекты слишком сложны, чтобы передавать их функциям, поскольку параметры функции «передаются по значению», то есть параметр получает копию передаваемого значения вместо самой переменной. Все время копируется целый объект.

По этой причине вы просто хотите сообщить различным функциям, где они могут найти объект. Вместо того, чтобы вручать копию объекта, вы вручаете копию адреса объекта. Адрес сохраняется в автоматическом режиме с типом указателя . (Это на самом деле просто целое число, но его размер определяется оборудованием и ОС, поэтому он должен быть специального типа.)

Объявление Дробь * myFraction; означает "myFraction - указатель, и, как вы знаете, он будет указывать на дробь позже."

Это автоматически выделит указатель , но не всю дробь. Чтобы это произошло, вы должны позвонить alloc и init .

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

В конечном счете, вы можете сделать такие заявления:

Fraction *myFraction = [[Fraction alloc] initWithNumerator: 2 Denominator: 3];

, который гласит: «Сделай мне Дробь, и сделай ее равной 2/3, а затем вставь адрес этой Дроби в myFraction».

0 голосов
/ 23 апреля 2011

Почему мы должны создать указатель для него? Почему бы нам не сделать настоящий экземпляр?

В Objective-C каждый объект имеет тип указателя. Итак, вам нужно использовать либо new, либо alloc/init.

Fraction *myFraction = [ Fraction new ] ;

или

Fraction *myFraction = [ [Fraction alloc] init ] ;

И myFraction нужно освободить.

Это первое выражение означает - дай мне указатель на новый экземпляр класса Fraction, не так ли?

Нет, вы просто объявляете указатель типа Fraction. И второе утверждение даже недействительно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...