objective-c协议代表

我正在理解代表如何工作,已经走过了一些例子,但现在用一个基本的testing应用程序,似乎我还没有得到它,

在这里我的代码:

类定义协议> * .h

#import <Foundation/Foundation.h> @protocol protoPerra <NSObject> -(void) dimeTuNombre:(NSString *) s; @end @interface MyClassic : NSObject { id<protoPerra> _delegate; } @property (assign) id<protoPerra> delegate; @end 

类实施协议> * .m

#import“MyClassic.h”

 @implementation MyClassic @synthesize delegate = _delegate; - (id)init { self = [super init]; if (self) { // Initialization code here. [[self delegate] dimeTuNombre:@"pinguete"]; } return self; } -(void) dealloc { [_delegate release]; _delegate = nil; [super dealloc]; } @end 

课程采用协议:

#import“MyClassic.h”@interface MainViewController:UIViewController(protoPerra)

.M

 #import "MainViewController.h" 
  @implementation MainViewController -(void) dimeTuNombre { NSLog(@"ss9!! tkt"); } - (void)viewDidLoad { [super viewDidLoad]; UILabel *lava = [[[UILabel alloc] initWithFrame:CGRectMake(30, 100, 100, 20)] autorelease]; lava.text = @"lava ss9"; [self.view addSubview:lava]; MyClassic *pirr = [[[MyClassic alloc] init ] autorelease]; [pirr setDelegate:self]; } -(void) dimeTuNombre:(NSString *)s { NSLog(@"%@",s); } @end 

所以在这个简单的例子中缺less什么使它与我的代理工作?

非常感谢!

请注意,我已经使用()采用类的.h中的<>,如同使用Chevrons,代码消失

你可以在MyClassic init中调用委托方法(dimeTuNombre :),但是委托还没有被设置,所以你需要重新思考什么时候调用dimeTuNombre:,或者重构MyClassic类来构造类似于

 -(id)initWithDelegate:(id<protoPerra>)delegate 

而不是简单的初始化。

为了澄清,在你当前的代码中,当你这样做的时候,你在MainViewController.h中设置了委托[pirr setDelegate:self]; – 将MyClassic属性的值“委托”设置为MainViewController的当前实例。 请注意,当你调用MyClassic的init时,委托还没有设置,所以[[self delegate] dimeTuNombre:@“pinguete”]; 呼叫什么都不做(代表在这一点上是零)。

你可以改变你的MyClassic构造函数,如下所示:

 -(id)initWithDelegate:(id<protoPerra>)aDelegate { self = [super init]; if (self) { _delegate = aDelegate; // Initialization code here. [[self delegate] dimeTuNombre:@"pinguete"]; } return self; } 

然后,而不是这个:

 MyClassic *pirr = [[[MyClassic alloc] init ] autorelease]; [pirr setDelegate:self]; 

你会这样做:

 MyClassic *pirr = [[[MyClassic alloc] initWithDelegate:self ] autorelease]; 

这将工作,但请注意,通常委托用于各种通知 – 如button报告它被点击或套接字说,它已收到一些数据。

我认为斯坦福大学的Paul Hegarty在第9课,iOS开发应用程序,2011秋季会议(在iTunes中提供,请查看Paul的博客)中提供了一个非常好的总结:

  1. 创build@protocol
  2. 将委托@property添加到委托者的public @interface
  3. 在委托人的实现中使用委托属性
  4. 在委托的@implmentation中的某处设置委托属性
  5. 在委托中实现协议的方法(在@interface上包含<>)

Paul还举了一个如何在计算器应用程序中使用协议的例子。

在这里输入图像说明

首先,创build协议:

 @protocol CalculatorProgramsTableViewControllerDelegate @optional - (void)calculatorProgramsTableViewController: (CalculatorPorgramTableViewController *)sender choseProgram:(id)program; @end 

第2步)。 在CalculatorProgramsTableViewController.h的表视图中,委托被定义为一个弱链接的id属性:

 @interface CalculatorProgramsTableViewController : UITableViewController ... // Define a property delegate @property (nonatomic, weak) id<CalculatorProgramsTableViewControlerDelegate> delegate; ... @end 

通过使用该协议,表格视图将能够发送关于程序改变的消息,但是视图不知道关于graphics视图。 这在下一步中完成。

步骤3)。 在表视图控制器中,委托用于发送有关更改的程序的消息:

 #progma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSeelectRowAtIndexPath:(NSIndexPath *)indexPath { id program = [self.programs objectAtIndex:indexPath.row]; [self.delegate calculatorProgramsTableViewController:self choseProgram:porgram]; } 

步骤4)。 代表在哪里? 它在calculatorGraphViewController中设置(分割视图中的右侧视图)。 当一个segue准备推出一个popup视图(table view)时,它将self设置为一个委托:

 @implementation CalculatorGraphViewController ... - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"Show Favorite Graphics"]) { NSArray * programs = [[NSUserDefaults standardUserDefaults] objectForKey:FAVORITES_KEY]; [segue.destinationViewController setPrograms:programs]; [segue.destinationViewController setDelegate:self]; // set delegate } } 

graphics视图不了解表视图,通信通道是由协议构build的,没有任何耦合就完美了! 为了让任何代表通过此协议回叫,graphics视图控制器的.h文件必须执行协议:

 // .h to implement the protocol @interface CalculatorGraphViewController :NSObject <CalculatorProgramsTableViewControllerDelegate> ... @end 

协议的方法在下一步的.m文件中定义。

最后一步。 代理的协议方法在segue的控制器中实现。 当select表视图中的一行时,协议的方法将被调用:

 // implement delegate method - (void)calculatorProgramsTableViewController:(CalculatorProgramsTableViewController *)sender chooseProgram:(id)program { self.calculatorProgram = program; } 

以上是在iOS应用程序中使用协议的典型方法。