Учебники

Протоколы Objective-C

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. Нет необходимости переопределять методы протокола в интерфейсе класса — достаточно принятия протокола.

Если вам нужен класс для принятия нескольких протоколов, вы можете указать их в виде списка через запятую. У нас есть объект делегата, который содержит ссылку на вызывающий объект, который реализует протокол.

Пример показан ниже.

Live Demo

#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 во избежание утечек памяти.