Шрифт:
Внутри процедуры main вы определяете переменную с именем myFraction: Fraction *myFraction;
Здесь указывается, что myFraction является объектом типа Fraction, то есть myFraction используется для хранения значений из вашего нового класса Fraction. Звездочка (*) перед myFraction является обязательным элементом. Технически она обозначает, что myFraction является на самом деле ссылкой (или указателем — pointer) на Fraction. Мы рассмотрим ссылки позднее.
Теперь, когда у нас имеется объект для хранения дроби (Fraction), нужно создать саму дробь. myFraction = [Fraction alloc];
alloc — это сокращение от allocate (выделить). Вам нужно выделить пространство в памяти для новой дроби. С помощью этого выражения происходит отправка сообщения новому классу Fraction: [Fraction alloc]
Вы обращаетесь к классу Fraction для применения метода alloc, но вы не опре-деляли метод alloc. Он был унаследован из родительского класса. Эта тема рас-сматривается в главе 8.
Отправив классу сообщение alloc, вы получаете в ответ новый экземпляр этого класса. В программе 3.2 возвращаемое значение сохраняется внутри переменной myFraction. Метод alloc очищает все переменные экземпляра объекта. Затем вам нужно инициализировать объект после выделения памяти для него.
Это выполняет оператор: myFraction = [myFraction init];
Здесь используется метод init, который инициализирует экземпляр класса. Сообщение init отправляется в myFraction. Вам нужно инициализировать конк-ретный объект Fraction, поэтому вы отправляете сообщение не классу, а экземп-ляру этого класса.
Метод init возвращает также значение — инициализированный объект. Это возвращаемое значение сохраняется в переменной myFraction. Эта последовательность из двух строк (выделение памяти для нового экземпляра класса и последующая его инициализация) выполняется в Objective-C так часто, что два сообщения обычно объединяются: myFraction = [[Fraction alloc] init];
Сначала выполняется оценка внутреннего выражения: [Fraction alloc]
Результатом этого выражения является конкретный выделяемый элемент типа Fraction. Вместо сохранения результата выделения в переменной, как это было сделано выше, к нему непосредственно применяется метод init. Таким образом, здесь снова выделяется сначала новый элемент типа Fraction, и затем происходит его инициализация. Результат инициализации присваивается переменной myFraction.
Для сокращения записи выделение памяти и инициализация часто встра-иваются непосредственно в строку объявления: Fraction *myFraction = [[Fraction alloc] init];
Мы часто используем этот стиль в книге, поэтому важно, чтобы вы понимали его. Вы видели выше, как действует автоматически высвобождаемый пул (autorelease pool): NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Здесь сообщение alloc отправляется классу NSAutoreleasePool для запроса о создании нового экземпляра. Затем этому новому созданному объекту отправ-ляется сообщение init для его инициализации.Теперь, вернувшись к программе 3.2, вы можете задать значение дроби. // Set fraction to 1/3 [myFraction setNumerator: 1]; [myFraction setDenominator: 3];
В первом операторе выполняется отправка сообщения setNumerator: переменной myFraction. Для аргумента указывается значение 1, и управление передается методу setNumerator:, который был определен для класса Fraction. Система Objective - С «понимает», что это метод изданного класса, поскольку «знает», что myFraction является объектом из класса Fraction.
Внутри метода setNumerator: переданное значение 1 сохраняется в перемен-ной п. В единственной программной строке метода это значение сохраняется в переменной экземпляра numerator. Фактически вы присваиваете элементу numerator в myFraction значение 1.
Затем следует сообщение для обращения к методу setDenominator: в myFraction. Значение аргумента 3 присваивается переменной d внутри метода setDenominator:. Это значение затем сохраняется в переменной экземпляра denominator, что завершает присваивание значения 1/3 переменной myFraction. Теперь можно вывести на экран значение дроби. // display the fraction using the print method NSLog (@The value of myFraction is:"); [myFraction print];
В результате вызова NSLog выводится текст: The value of myFraction is: (Значение myFraction:)
В следующем выражении для сообщения вызывается метод print: [myFraction print];
Внутри метода print выполняется вывод значений переменных экземпляра numerator и denominator, разделенных наклонной чертой.
Следующее сообщение в программе освобождает память, которая исполь-зовалась для этого объекта Fraction: [myFraction release];
Это критически важная часть в практике программирования. При создании каждого нового объекта вы запрашиваете память, выделяемую для объекта. За-кончив работу с объектом, вы обязаны освободить эту память. Память осво-бождается автоматически, когда происходит завершение программы, но при разработке сложных приложений вам придется работать с сотнями (или тыся-чами) объектов, которые используют много памяти. Если не освобождать память во время работы программы, то это может замедлить ее выполнение. Поэтому возьмите за правило освобождать память, как только это можно сделать.