Расширение класса — это безымянная категория, отдельно существующая как раздел интерфейса, например, следующим образом:

@interface MyClass ()

11 здесь следует конкретное наполнение

end

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

// MyClass.ш:

Sinterface MyClass ()

// здесь следует конкретное наполнение

@end

(^implementation MyClass (

// переменные экземпляра

}

// методы

@end

Это типичный порядок расположения расширений определенных классов, принятый в файлах шаблонов для проектов, выполняемых в Xcode. Например, в рассматриваемом здесь проекте Empty Window расширение класса находится в начале файла ViewController . m. Можете убедиться в этом сами!

Каким же должно быть “наполнение” расширения класса для того, чтобы сделать его настолько полезным, чтобы оно оказалось в файле шаблона? Прежде всего следует отметить, что расширение класса служило раньше в качестве стандартного решения проблемы, связанной с порядком определения методов.

До внедрения усовершенствований в компилятор LLVM языка Objective-C в версии 3.1 (Xcode 4.3) один метод из раздела реализации не мог вызвать другой метод из того же самого раздела, если только он не был определен или объявлен раньше другого метода. Упорядочить определение методов не так-то просто, и поэтому вполне очевидным выходом из этого затруднительного положения является объявление метода, которое можно сделать только в разделе интерфейса. В то же время для того чтобы разместить объявление метода в разделе интерфейса, придется перейти к другому, заголовочному файлу, что не совсем удобно, а еще хуже — метод становится в итоге открытым и доступным для вызова из любого класса, в котором импортируется этот заголовочный файл. В этом нет ничего страшного, если данный метод предполагается сделать открытым, но что, если требуется оставить его закрытым? Решение этого вопроса состоит в размещении расширения класса в начале его файла реализации. Если разместить объявления методов в этом расширении класса, то их объявления будут доступны всем методам из раздела реализации, а следовательно, оно смогут вызывать друг друга, хотя и не будут доступны для другого класса.

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

Например, в главе 7 свойство IBOutlet было объявлено в заголовочном файле класса. Однако на практике такое свойство, скорее всего, будет объявлено в расширении класса, находящемся в файле реализации. Выходы класса обычно не имеют другого назначения в классе. Еще одно применение расширений классов рассматривается в следующем разделе.


 

 

 

Добавить комментарий