Программирование на Objective-C 2.0
Шрифт:
Если fp — указатель на функцию, то соответствующую функцию можно вызвать, написав fp
или (*fp) Если функция принимает аргументы, они должны быть указаны в круглых скобках. Классы
В этом разделе приводятся сведения о синтаксисе и семантике классов. Определение класса
В определение класса включается объявление переменных экземпляра и мето-дов в секции interface, а также определение кода для каждого метода в секции implementation. Секция interface Общий формат @interface имяКласса: родительскийКласс <протокол, ...> { объявления ПеременныхЭкземлляра } объявлениеМегода объявлениеМегода @end
Класс имяКласса объявляется с помощью родительского
Если двоеточие и родительскийКласс не указаны, это означает, что объявляется новый корневой класс. Объявления переменных экземпляра
В необязательной секции объявленияПеременныхЭкземплярауказываются тип и имя каждой переменной экземпляра для данного класса. Каждый экземпляр класса имяКласса получаег свой собственный набор этих переменных плюс переменные, наследуемые из класса родительскийКласс. Доступ к таким переменным можно осуществлять непосредственно по имени в методах экземпляра, определенных в классе имяКласса, или из подклассов класса имяКласса. Если доступ ограничен директивой @private, то подклассы не могут осуществлять доступ к таким пере-менным (см. выше раздел «Переменные экземпляра»).
Методы класса не имеют доступа к переменным экземпляра. Объявления свойств
Общий формат @property {атрибуты) списокИмен-,
Объявляются свойства с помощью заданного списка атрибутов с разделите лями-запятыми.
списокИмен — это список с разделителями-запятыми, содержащий имена свойств объявляемого типа. {тип) имяСвойства1, имяСвойства2, имяСвойстваЗ,...
Директива @property может присутствовать в любом месте секции объявления метода для класса, протокола или категории.
Табл. В.7. Атрибуты свойств Атрибут Описание assign Используется простое присваивание, чтобы задать значение переменной экземпляра в методе-установщике (setter). (Это атрибут по умолчанию.) сору Используется метод сору, чтобы задать значение переменной экземпляра. getter=имя Используется имя для имени метода-получателя (getter) вместо имени имяСвойства, которое используется по умолчанию для синтезируемого метода-получателя. nonatomic Значение может быть возвращено непосредственно из синтезируемого метода-получателя. Если этот атрибут не объявлен, то методы доступа (accessor) действуют с атрибутом atomic; это означает, что доступ к переменным экземпляра защищен блокировкой mutex. Это обеспечивает защиту в среде с несколькими потоками за счет того, что операция get или set выполняется только в одном потоке. Кроме того, по умолчанию в среде без сборки мусора синтезируемый метода-получатель будет удерживать (retain) и автоматически высвобождать (autorelease) свойство, прежде чем возвратить его значение. ~fwrite Значение свойства можно читать и задавать. Компилятор предполагает, что вы сами предоставили метод-получатель и метод-установщик (getter и setter), или он будет синтезировать оба метода, если используется директива @synthesize. retain Свойство должно удерживаться (retain) во время присваивания. Этот атрибут можно указывать только для типов Objective-C. setter=имя Используется имя для имени метода-установщика (setter) вместо заданного имени имяСвойства, которое используется по умолчанию для синтезируемого метода доступа.
Можно указывать только один из атрибутов assign, сору или retain. Если у вас не используется сборка мусора, то один из этих атрибутов должен быть использован явным образом; в противном случае вы получите предупреждение от компилятора. Если у вас используется сборка мусора и вы не указали один из этих трех атрибутов, то будет применяться атрибут по умолчанию assign. В этом
случае компилятор выдаст предупреждение, только если данный класс подчиняется протоколу NSCopying (в этом случае для свойства может потребоваться атрибут сору, а не assign). Если вы используете атрибут сору, то синтезируемый метод-установщиком применяет метод сору данного объекта. Это дает немутабельную копию. Если вам требуется мутабсльная копия, то вы можете предоставить вместо этого свой собственный метод-установщик. Объявление методаОбщий формат мТип (возвращаемыйТип) имя??1: (тип1) парам 1 имя??2: (тип2) парам2, ...;
Объявляется метод имя 1:имя2:.., который возвращает значение типа возвраща-емыйТип; он имеет формальные параметры парам1, парам2\ ларам/ объявляется с типом 7ил/, парам2с типом тип2, и т.д.
Любое из имен после имя/ (то есть имя2,...) можетбыть опущено; в этом слу-чае все же используется двоеточие в качестве заполнителя, и оно становится частью имени метода (см. следующий пример).
Если в качестве м Тил указан знак +, это означает, что объявляется метод класса, а если знак -, то объявляется метод экземпляра.
Если объявляемый метод наследуется из родительского класса, то новое определение подавляет определение родительского класса. В этом случае все же имеется доступ к методу родительского класса, и для этого нужно передать сообщение к super. Вызов методов класса происходит, когда соответствующее сообщение передается объекту-классу, а вызов методов экземпляра происходит, когда соответствующее сообщение передается экземпляру класса. Методы класса и методы экземпляра могут иметь одинаковые имена.
Одинаковое имя метода может также использоваться в различных классах. Способность объектов различных классов реагировать на методы с одинако-выми именами называется полиморфизмом (polymorphism).
Если метод не возвращает значения, то возвращаемыйТип указы вас гея как void. Если метод возвращает значение типа id, то возвращаемыйТип можно не указывать, хотя практика надежного программирования рекомендует указы вать id к? возвращаемый тип.
Если используется ,... в качестве последнего (или единственного) параметра в списке, то метод принимает переменное число параметров, например, -(void) print: (NSSTRING *) format, ... { }
Ниже приводится пример объявления класса в секции interface: объявляется класс с именем Fraction, родительским классом для которого является NSObject. @interface Fraction: NSObject { int numerator, denominator; ) +(Fraction *) newFract; -(void) setTo: (int) n : (int) d; -(void) setNumerator: (int) n andDenominator: (int) d; -(int) numerator; -(int) denominator; @end
Класс Fraction имеет две целые переменные экземпляра с именами numerator и denominator. Он также содержит один метод класса с именем newFract, который возвращает объект типа Fraction. В него включены также два метода экземпляра с именами setTo:: и setNumerator:andDenominator:. Каждый из них принимает два аргумента и не возвращает никакого значения. В нем содержатся также два метода экземпляра с именами numerator и denominator, которые не принимают никаких аргументов и возвращают значение типа int. Секция implementation Общий формат @implementation имяКласса; определениеМетода определениеМетода ... @end
Определяется класс с именем имяКлаеса. Родительский класс и переменные экземпляра обычно не объявляются повторно в секции implementation (хотя это можно делать), поскольку они уже объявлены ранее в секции interface.
Если реализуются методы ые из какой-либо категории (см. ниже раздел «Оп-ределение категории»), то в секции implementation должны быть определены все методы, объявленные в секции interface. Если в секции interface были указаны один или несколько протоколов, то должны быть определены все методы этих протоколов — неявным образом через наследование или явным образом путем определения в секции implementation.