2009-10-30 174 views
1

我最近开始尝试在我的Objective-C开发中使用协议,作为(更明显的)在我的类中更适当地委托任务的方式。我完全理解协议的基本概念及其工作原理。然而,当我尝试创建一个自定义协议并转而实现另一个协议时,我碰到了一个障碍。我自从发现了解决方案,但我很好奇,为什么下面不工作:协议内的Objective-C协议

@protocol STPickerViewDelegate <UIPickerViewDelegate> 

- (void)customCallback; 

@end 

@interface STPickerView : UIPickerView 
{ 
    id <STPickerViewDelegate> delegate; 
} 

@property (nonatomic, assign) id <STPickerViewDelegate> delegate; 

@end 
在一个视图控制器,符合 STPickerViewDelegate

然后:

STPickerView * pickerView = [ [ STPickerView alloc ] init ]; 
pickerView.delegate = self; 

- (void)customCallback 
{ 
    ... 
} 

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component 
{ 
    ... 
} 

的问题是,pickerView:titleForRow:forComponent:从未被调用。另一方面,customCallback被称为很好,这并不令人感到意外。我不明白为什么STPickerViewDelegate本身符合UIPickerViewDelegate,当UIPickerViewDelegate的事件应该发生时,不会通知我的视图控制器。根据我对Apple文档的理解,如果协议(A)本身符合另一个协议(B),那么符合第一协议(A)的类(C)也必须符合第二协议(B),即正是我想要的和期望的行为。

我最终什么事做的是去除STViewPickerid<STPickerViewDelegate> delegate财产,而不是做这样的事情在我的STViewPicker执行以下命令,其中我想唤起customCallback

if ([ self.delegate respondsToSelector:@selector(customCallback) ]) 
{ 
    [ self.delegate performSelector:@selector(customCallback) ]; 
} 

这只是正常的,但我真的很对于我原来的方法不起作用感到困惑。

回答

3

问题是UIPickerView已经有一个委托成员变量,并且你正在设置的子类中声明另一个,而超类的委托变量保持为零,因此任何委托方法都不会被调用你期望它被调用的类。在这种情况下,你所做的几乎是唯一的方法;如果您需要扩展给定的协议,请使用类实现,然后将该类设置为UIPickerView的委托。

编辑:顺便说一句,真棒化身:)

+0

的答案是如此明显,一旦有人点出来,是吗? :)我想我的大脑真的很累。是的,我们的母亲恋人必须坚持在一起。 :d – LucasTizma 2009-10-30 20:56:34

0

我试图做同样的事情 - 我想你想你添加到UIImagePickerControllerDelegate在一个文件组额外的方法?我从两个地方运行UIImagePicker,并希望它在没有重复代码的情况下以相同的方式运行。

我所做的就是向UIViewController添加一个类别,就像这样(下面)。对于Objective-C(已经使用C++多年)而言,我相当新,所以很可能违反了你的精神“假设”做事(扩展协议更有意义),但是我的方法完成了我想要的,所以我认为我会抛弃它。

的UIViewController + imagePickerDelegate.h:

@interface UIViewController (ImagePickerDelegate) <UINavigationControllerDelegate, UIImagePickerControllerDelegate> 

    -(void)configurePicker:(UIImagePickerController*)picker; 
    ... 

@end 

的UIViewController + imagePickerDelegate.m:

#import "UIViewController+imagePickerDelegate.h" 

    @implementation UIViewController (ImagePickerDelegate) 

    -(void)configurePicker:(UIImagePickerController*)picker 
    { 
     picker.delegate = self; 
     picker.allowsEditing = YES; 
    } 

    .... 

@end