如何在目标C中创建委托人?

时间:2011-12-12 14:51:06

标签: objective-c cocoa-touch delegates

我正在努力学习,如何在目标C中实现委托模式。但讨论几乎专注于协议的采用,然后实施委托方法带有特定的协议 - 或 - 单独的委托原则 - 或单独的协议。

我无法找到的是一个易于理解的材料,关于如何编写将作为委托人的类。我的意思是这个类,一些事件的消息将来自哪个类,它将提供接收该消息的协议 - 一种2in1描述。 (协议和授权)。

为了我的学习目的,我想使用一个iPhone,一个Cocoa touch应用程序和Xcode4.2,使用ARC,没有故事板或NIB,继续下面这个简单的例子。

让我们有一个名为“Delegator”的类,它是NSObject的子类。 Delegator类具有名为“report”的NSString实例变量,并采用UIAccelerometerDelegate协议。在Delegator实现中,我将实现委托方法

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

这个委托方法将创建一个NSString @“myReport”,并在有加速度计事件的任何时候将其存储在报告变量中。此外,我想要一个名为ReportsStorage(NSobject的子类)的第二个类,它可以在其名为latestReport的实例变量中存储一些Nsstring(report)。 到现在为止还挺好。 现在让我们回到Delegator Class。我想在Delegator中实现一个名为ReportsDelegate的协议,该协议将通知采用它的类(ReportsStorage类),生成报告并通过委托方法传递此报告,该方法应该(我相信)类似于此

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

请您提供代理类(包括“委托”属性)的代码,这将实现此目的,并描述每行代码的含义?

提前致谢,EarlGrey

1 个答案:

答案 0 :(得分:3)

您需要将委托属性声明为id<ReportsDelegate>类型。也就是说,任何符合ReportsDelegate协议(id)的对象类型(<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