【问题标题】:Objective-C Protocols within Protocols协议中的 Objective-C 协议
【发布时间】:2009-10-30 16:44:57
【问题描述】:

我最近开始尝试在我的 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),即正是我想要和预期的行为。

我最终做的是从STViewPicker 中删除id&lt; STPickerViewDelegate &gt; delegate 属性,而是在我想要唤起customCallbackSTViewPicker 实现中执行以下操作:

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

这很好用,但我真的很困惑为什么我原来的方法不起作用。

【问题讨论】:

    标签: objective-c inheritance uikit protocols


    【解决方案1】:

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

    编辑:顺便说一句,真棒头像:)

    【讨论】:

    • 一旦有人指出答案,答案就很明显了,嗯? :) 我想我的大脑真的很累。是的,我们爱母亲的人必须团结在一起。 :D
    【解决方案2】:

    我尝试做类似的事情 - 我假设您想将添加到 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多