Как создать делегат в цели C? - PullRequest
2 голосов
/ 12 декабря 2011

Я пытаюсь узнать, как реализовать шаблон делегирования в цели C. Но обсуждение почти исключительно сосредоточено на принятии протоколов и затем реализации методов делегата , которые идут с конкретный протокол - или - только принцип делегирования - или только протоколы.

То, что я не могу найти, это простой для понимания материал о том, как написать класс, который будет выполнять функции делегатора. Под этим я подразумеваю класс, из которого поступит сообщение о каком-либо событии и который предоставит протокол для получения этого сообщения - своего рода описание 2 в 1. (протоколы и делегирование).

В целях обучения я хотел бы пойти по следующему тривиальному примеру, используя iPhone, сенсорное приложение Cocoa и Xcode4.2, используя ARC, без раскадровки или NIB.

Давайте иметь класс с именем «Delegator», который является подклассом NSObject. Класс Delegator имеет переменную экземпляра NSString с именем «report» и принимает протокол UIAccelerometerDelegate. В реализации Delegator я буду реализовывать метод делегата

-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration 

Этот метод делегата создаст NSString @ "myReport" и сохранит его в переменной отчета каждый раз, когда происходит событие акселерометра. Кроме того, я хочу иметь второй класс с именем ReportsStorage (подкласс NSobject), который может хранить некоторую Nsstring (отчет) в своей переменной экземпляра с именем latestReport. Все идет нормально. Теперь вернемся к классу Delegator. Я хотел бы реализовать в Делегаторе протокол с именем ReportsDelegate, который уведомит класс, который его принимает (класс ReportsStorage), о том, что отчет был сгенерирован, и пропустит этот отчет через метод делегата, который должен быть (я считаю) чем-то вроде это

-(void)delegator:(Delegator *)delegator didCreateNewReport:(NSString *)report;

Не могли бы вы предоставить код для класса Delegator (в том числе свойство «делегат»), который достигнет этого, с описанием того, что означает каждая строка кода?

Заранее спасибо, ЭрлГрей

1 Ответ

3 голосов
/ 12 декабря 2011

Вам необходимо объявить свойство делегата как тип id<ReportsDelegate>.То есть любой тип объекта (id), соответствующий протоколу ReportsDelegate (<ReportsDelegate>).Затем, если метод делегата считается необязательным, проверьте, отвечает ли делегат на этот селектор, прежде чем вызывать его.(respondsToSelector:).

Примерно так:

Delegator.h

#import <Foundation/Foundation.h>

// Provide a forward declaration of the "Delegator" class, so that we can use
// the class name in the protocol declaration.
@class Delegator;

// Declare a new protocol named ReportsDelegate, with a single optional method.
// This protocol conforms to the <NSObject> protocol
@protocol ReportsDelegate <NSObject>
@optional
-(void)delegator:(Delegator *)delegator didCreateNewReport:(NSString *)report;
@end

// Declare the actual Delegator class, which has a single property called 'delegate'
// The 'delegate' property is of any object type, so long as it conforms to the
// 'ReportsDelegate' protocol
@interface Delegator : NSObject
@property (weak) id<ReportsDelegate> delegate;
@end

Delegator.m

#import "Delegator.h"

@implementation Delegator
@synthesize delegate;

// Override -init, etc. as needed here.

- (void)generateNewReportWithData:(NSDictionary *)someData {

    // Obviously, your report generation is likely more complex than this.
    // But for purposes of an example, this works.
    NSString *theNewReport = [someData description];

    // Since our delegate method is declared as optional, check whether the delegate
    // implements it before blindly calling the method.
    if ([self.delegate respondsToSelector:@selector(delegator:didCreateNewReport:)]) {
        [self.delegate delegator:self didCreateNewReport:theNewReport];
    }
}

@end
...