我在哪里放置委托方法以及如何调用它们?

时间:2012-05-22 20:36:13

标签: iphone ios delegates

作为一名新的iOS开发人员,我终于偶然发现了各位代表。我正在尝试遵循教程:http://gabriel-tips.blogspot.com/2011/05/input-accessory-view-how-to-add-extra.html,但我很难理解我应该放置实际的委托方法的位置。

其次,是否有人会介意如何调用委托方法?

谢谢!

3 个答案:

答案 0 :(得分:1)

委托只是一个同意为另一个班级工作的班级。委托类调用委托方法。因此,代表必须提供适当方法的实施。让我们创建一个带有表视图的简单视图控制器。

// 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合适时(用户选择一行)将由myTableView调用。

在这里,您可以找到UITableViewDelegate中定义的所有委托方法。有些是必需的,有些是可选的:

http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html

为了成为一个类的委托,你应该知道你需要为哪些方法提供实现。

如果要创建自己的委托定义,可以创建新协议。您不保留您的委托(请参阅属性声明),因为这会创建一个保留周期:

// 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

现在,委托可以接收消息,并且知道我的视图控制器更改了选择,然后执行它想要的操作。

答案 1 :(得分:1)

委托模式是允许独立控制器之间进行通信的便捷方式,允许松散耦合。所以,假设您有这样的模式:

        A
       / \
      B   C

其中A实例化B和C.在A到B和A到C之间进行通信很容易,但是如何在B和C之间进行通信? B到A? C到A?您可以通过几种不同的方式执行此操作,例如键值观察或块回调。尽管如此,代表团仍然最常使用,尽管Block正在变得强大。

在此示例中,对象A实例化对象B以创建对象并用信息填充它。对象B如何将新对象传递回A,因为您希望保持松散?那么,通过这9个简单的步骤,你也可以做到!它可能没有意义,但我们将从ClassB开始......

// 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
  1. 定义稍后将建立的协议
  2. 设置符合该协议的对象实例
  3. 设置协议
  4. 设置您将用于将finishedObject发送回A的方法调用。
  5. 合成代理
  6. 执行完所需操作后,使用该方法将其发回 你在4中定义了

  7. // 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.在获得新对象时实现委托方法。

    所以这个过程,简而言之就是:一个实例B.A将B的代表设置为自我。 A告诉B做某事。 B做某事并通过委托方法发回对象。 A得到它。

    有关更多信息,包括您可以使用协议执行的操作,请查看: Big Nerd Ranch谈论协议 Part 1 Part 2 Part 3

    祝你好运!

答案 2 :(得分:0)

看起来你可能会对代表是什么以及如何使用它们感到困惑。以下是您可能会发现有用的Apple文档的两个链接:A conceptual overview和更多in depth explaination