作为一名新的 iOS 开发人员,我终于偶然发现了代表。我正在尝试遵循一个教程: http: //gabriel-tips.blogspot.com/2011/05/input-accessory-view-how-to-add-extra.html,但我很难理解我在哪里我应该放置实际的委托方法。
其次,有人介意提供一个关于如何调用委托方法的简单解释吗?
谢谢!
作为一名新的 iOS 开发人员,我终于偶然发现了代表。我正在尝试遵循一个教程: http: //gabriel-tips.blogspot.com/2011/05/input-accessory-view-how-to-add-extra.html,但我很难理解我在哪里我应该放置实际的委托方法。
其次,有人介意提供一个关于如何调用委托方法的简单解释吗?
谢谢!
委托只是一个同意为另一个班级工作的班级。委托方法由委托类调用。因此,委托必须提供适当方法的实现。让我们用表格视图制作一个简单的视图控制器。
// MyViewController.h
@interface MyViewController : UIViewController <UITableViewDelegate>
@property (nonatomic, retain) UITableView *myTableView;
@end
在 MyViewController.h 文件中,我已将我的视图控制器声明为 UITableViewDelegate 类型的委托(这实际上意味着它实现了 UITableViewDelegate 协议。稍后会详细介绍)。因此,我同意响应对我的视图控制器的请求。请求将来自名为 myTableView 的表视图。然而,仅仅声明我遵守 UITableViewDelegate 并不能使我的视图控制器成为任何事物的代表。我必须直接指定:
// MyViewController.m
#import "MyViewController.h"
@implementation MyViewController
- (void)loadView
{
myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
myTableView.delegate = self;
self.view = myTableView;
}
@end
这里我专门设置了 MyViewController 为 myTableView 的代理。现在,每当表视图想要请求其委托做某事时,它都会将该消息发送到我的视图控制器。因此,MyViewController 必须提供适当委托方法的实现:
// MyViewController.m
#import "MyViewController.h"
@implementation MyViewController
- (void)loadView
{
myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
myTableView.delegate = self;
self.view = myTableView;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"Selected section:%i row:%i", indexPath.section, indexPath.row);
}
@end
在这里,我提供了委托方法 tableView:didSelectRowAtIndexPath: 的实现,myTableView 将在适当的时候调用它(用户选择一行)。
在这里你可以找到 UITableViewDelegate 中定义的所有委托方法。有些是必需的,有些是可选的:
为了成为一个类的委托,你应该知道你需要为哪些方法提供实现。
如果您想创建自己的委托定义,您将创建一个新协议。您不保留您的代表(请参阅属性声明),因为这会创建一个保留周期:
// MyViewController.h
@class MyViewController;
@protocol MyViewControllerDelegate
- (void)viewController:(MyViewController *)viewController didChangeSelection:(NSIndexPath *)newIndexPath;
@end
@interface MyViewController : UIViewController <UITableViewDelegate>
@property (nonatomic, retain) UITableView *myTableView;
@property (nonatomic, assign) id<MyViewControllerDelegate> delegate;
@end
在这里,我们创建了一个新协议。任何想要响应 viewController:didChangeSelection: 消息的类现在都可以这样做。就像上面的表格视图一样,它将委托设置为自身,然后实现该方法。现在您有了委托,您可以在适当的时候调用该方法。
// MyViewController.m
#import "MyViewController.h"
@implementation MyViewController
- (void)loadView
{
myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
myTableView.delegate = self;
self.view = myTableView;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"Selected section:%i row:%i", indexPath.section, indexPath.row);
indexPath = [NSIndexPath indexPathForRow:1 inSection:0];
[self.delegate viewController:self didChangeSelection:indexPath];
}
@end
现在,委托可以接收消息并知道我的视图控制器更改了选择来做它想做的事情。
委托模式是一种方便的方式,允许独立控制器之间的通信,允许松散耦合。因此,假设您有这样的模式:
A
/ \
B C
A 实例化 B 和 C 的地方。在 A 到 B 和 A 到 C 之间进行通信很容易,但是您将如何在 B 和 C 之间进行通信?B到A?C到A?有几种不同的方法可以做到这一点,例如键值观察或块回调。不过,尽管 Blocks 越来越强大,但委派仍然是最常用的。
在此示例中,对象 A 实例化对象 B 以创建一个对象并用信息填充它。当您想让事情保持松散时,对象 B 如何将新对象传递回 A?那么,通过这9个简单的步骤,你也可以做到!这可能没有意义,但我们将从 ClassB 开始……</p>
// ClassB.h
@protocol ClassBDelegate; //(1)
@interface ClassB : NSObject
@property (nonatomic, weak) id<ClassBDelegate>bDelegate; //(2)
-(void)makeNewObjectAndSendBack;
@end
@protocol ClassBDelegate : NSObject //(3)
-(void) classB:(Class B *)theClassB finishedWithObject:(id)finishedObject; //(4)
@end
ClassB.m
@implementation
@synthesize bDelegate = _bDelegate; //(5)
-(void)makeNewObjectAndSendBack {
//something something something
[self.bDelegate classB:self finishedWithObject:newObject]; //(6)
}
@end
// ClassA.h
@interface ClassA : NSObject <ClassBDelegate> //(7)
@property (nonatomic, strong) ClassB theClassB;
-(void)yourMethodToDoSomething;
@end
ClassA.m
@implementation
@synthesize theClassB = _theClassB;
-(void)randomMethod {
self.theClassB = [ClassB new];
self.theClassB.bDelegate = self; //(8)
[self.theClassB makeNewObjectAndSendBack];
}
-(void) classB:(Class B *)theClassB finishedWithObject:(id)finishedObject { //(9)
[self doSomethingWithFinishedObject:finishedObject]; //ta-da!
}
@end
7.符合ClassBDelegate协议。这基本上说您将实现协议定义中定义的方法。
8.设置classB对象的委托对象为self!这是至关重要的,经常被跳过。
9.当你取回新对象时,实现委托方法。
所以这个过程,简而言之就是:A实例化B。A将B的委托设置为自己。A告诉B做某事。B 做某事并通过委托方法将对象发回。A拿回来了。
有关更多信息,包括您可以使用协议做什么,请查看:Big Nerd Ranch 谈论协议 第 1 部分第 2 部分第 3 部分
祝你好运!