正确实施代表和协议

时间:2010-11-21 21:30:28

标签: iphone cocoa cocoa-touch delegates protocols

我创建了这个测试用例,作为我问题的一个简单例子。

  • AppDelegate初始化TestViewController并将其添加到窗口
  • TestViewController初始化TestView并使其成为视图
  • TestView初始化TestSubView并将其添加为子视图

我的目标是通过委托允许TestSubView访问TestViewController的方法&变量。在此示例中,TestSubView通过touchesBegan或touchesMoved访问方法。

请帮助。谢谢。

编辑:虽然没有更多错误,但仍无法正常工作。我做了什么:将协议定义移动到一个单独的文件并导入它,保留分配,并删除标题开头的@protocol TestDelegate声明。

我认为我的问题是我没有在TestViewController.m中分配委托,如果这是问题,我该怎么做?

TestViewController.h

#import <UIKit/UIKit.h>

@interface TestViewController : UIViewController <TestDelegate> {

    int number;
}

-(void)assignNumber:(int)value;
-(void)displayNumber;

@property int number;

@end

移至protocol.h并在需要时导入

@protocol TestDelegate

-(void)assignNumber:(int)value;
-(void)displayNumber;

@end

TestViewController.m

#import "TestViewController.h"
#import "TestView.h"

@implementation TestViewController

@synthesize number;

- (void)loadView {
    TestView *myView = [[TestView alloc] initWithFrame:CGRectMake(0,0,320,480)];
    self.view = myView;
    [myView release];
}

-(void)assignNumber:(int)value {
    NSLog(@"Number Assigned");
    number = value;
}

-(void)displayNumber {
    NSLog(@"%i",number);
}

TestSubView.h

#import <UIKit/UIKit.h>
#import "TestViewController.h"


@interface TestSubView : UIView {

    id<TestDelegate> delegate;
}

@property (nonatomic, retain) id<TestDelegate> delegate;

@end

TestSubView.m

#import "TestSubView.h"
#import "TestViewController.h"

@implementation TestSubView

@synthesize delegate;

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        // Initialization code
        [self setBackgroundColor:[UIColor redColor]];
        [self setUserInteractionEnabled:YES];
    }
    return self;
}


- (void)dealloc {
    [super dealloc];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    [self.delegate assignNumber:5];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    [self.delegate displayNumber];  
}

2 个答案:

答案 0 :(得分:0)

首先,您要声明一个协议,然后分配与实现该协议相同的对象。您可能正在寻找的是在TestSubView上声明TestDelegate协议。另外,在为委托设置属性时,请务必使用'assign'关键字而不是'retain'。

最后,通过使用UIGestureRecognizer可以大大简化所有这些。您可以在控制器中进行设置并将其添加到testSubView中。这样,当视图识别出相应的手势发生在其边界内时,将向控制器发送一条消息,允许您执行分配或显示数字所需的操作。

答案 1 :(得分:0)

当您的班级被调用TestView时,您指的是TestSubView,除非您定义了2个班级。

TestView *myView = [[TestView alloc] initWithFrame:CGRectMake(0,0,320,480)];

你说你还没有指派代表是对的 你会在下一行做到这一点:

myView.delegate = self;

最终得到这个:

- (void)loadView {
    TestSubView *myView = [[TestSubView alloc] initWithFrame:CGRectMake(0,0,320,480)];
    myView.delegate = self; // Set Delegate Here
    self.view = myView;
    [myView release];
}