Objective-C позволяет вам определять протоколы, которые объявляют методы, которые предполагается использовать для конкретной ситуации. Протоколы реализуются в классах, соответствующих протоколу.
Простым примером может быть класс обработки сетевых URL-адресов, у него будет протокол с такими методами, как метод делегата processCompleted, который интимирует вызывающий класс после завершения операции получения сетевого URL-адреса.
Синтаксис протокола показан ниже.
@protocol ProtocolName @required // list of required methods @optional // list of optional methods @end
Методы под ключевым словом @required должны быть реализованы в классах, соответствующих протоколу, а методы под ключевым словом @optional являются необязательными для реализации.
Вот синтаксис для класса, соответствующего протоколу
@interface MyClass : NSObject <MyProtocol> ... @end
Это означает, что любой экземпляр MyClass будет реагировать не только на методы, объявленные специально в интерфейсе, но и на то, что MyClass также обеспечивает реализацию необходимых методов в MyProtocol. Нет необходимости переопределять методы протокола в интерфейсе класса — достаточно принятия протокола.
Если вам нужен класс для принятия нескольких протоколов, вы можете указать их в виде списка через запятую. У нас есть объект делегата, который содержит ссылку на вызывающий объект, который реализует протокол.
Пример показан ниже.
#import <Foundation/Foundation.h> @protocol PrintProtocolDelegate - (void)processCompleted; @end @interface PrintClass :NSObject { id delegate; } - (void) printDetails; - (void) setDelegate🙁id)newDelegate; @end @implementation PrintClass - (void)printDetails { NSLog(@"Printing Details"); [delegate processCompleted]; } - (void) setDelegate🙁id)newDelegate { delegate = newDelegate; } @end @interface SampleClass:NSObject<PrintProtocolDelegate> - (void)startAction; @end @implementation SampleClass - (void)startAction { PrintClass *printClass = [[PrintClass alloc]init]; [printClass setDelegate:self]; [printClass printDetails]; } -(void)processCompleted { NSLog(@"Printing Process Completed"); } @end int main(int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; SampleClass *sampleClass = [[SampleClass alloc]init]; [sampleClass startAction]; [pool drain]; return 0; }
Теперь, когда мы скомпилируем и запустим программу, мы получим следующий результат.
2013-09-22 21:15:50.362 Protocols[275:303] Printing Details 2013-09-22 21:15:50.364 Protocols[275:303] Printing Process Completed
В приведенном выше примере мы увидели, как методы delgate вызываются и выполняются. Он начинается с startAction, после завершения процесса вызывается метод делегата processCompleted для информирования о завершении операции.
В любом приложении iOS или Mac у нас никогда не будет программы, реализованной без делегата. Поэтому важно понимать использование делегатов. Объекты делегатов должны использовать тип свойства unsafe_unretained во избежание утечек памяти.