想不出一个直观的方式来解释这个问题的主题,我为此道歉。我的问题如下:
我有几个需要在UIDatePicker中调用的UIViewController。我不想多次将Date Picker子类化,因为它是相同的接口。我遇到的问题是找出Cocoa / Objective-C提供的工具,以便我抽象出我的子控制器,这样就不需要知道父控制器是谁实例化了它。父控制器只需要通过将self传递给某个子控制器实例变量来告诉子控制器他们是谁。问题是,子控制器无法在不导入类的接口文件的情况下访问父级的方法/实例变量。这再次意味着孩子知道调用它的每个父母。
寻找解决此问题的最佳方法,这似乎是非常常见的问题。
答案 0 :(得分:2)
如果您正在创建自定义UIDatePicker子类,或者您只是在几个不同的自定义UIViewController子类中实现UIDatePicker委托方法,那么问题就不明显了。
在任何一种情况下,我认为委托和协议的某种组合是您正在寻找的。
父控制器只需要 告诉孩子控制者他们是谁 通过将自己传递给某个孩子 控制器实例变量
这正是委托有用的内容。在Objective-C类中将其声明为类型id。如果你喜欢使用通常的语法,你可以把它变成一个属性。
id delegate;
现在,解决第二个问题:
问题在于,孩子 控制器无法访问 方法/实例变量 没有导入类的父级 界面文件
您绝对不希望直接访问ivars,在Objective-C中,您始终可以向任何对象发送任何消息(您将收到编译器警告,但这不是错误)。
有一种方法可以摆脱那些警告,称为协议。协议就像一个Java接口;它允许您定义方法列表,类可以声明它们实现协议。
创建协议的语法如下所示:
@protocol ProtocolName
- (void)sometMethod;
@end
当你声明你的类时,你说它实现了这样的协议:
@interface MyClass <MyProtocol>
使用逗号分隔列表来实现多个协议。
您想知道的最后一个技巧是如何定义一个需要asignee实现特定协议的指针。回到之前的代理实现,我们可以添加相同的尖括号语法,告诉编译器我们期望我们分配的对象实现此协议。
id<MyProtocol> delegate;
您可以在自己的文件中声明协议,并且只需要在使用该协议的任何类中导入该协议文件。您还可以结合上面的August的建议使用它,并在公共基本控制器对象中实现通用功能,具有基于每个自定义控制器子类。
(协议的另一个概述:http://en.wikipedia.org/wiki/Objective-C#Protocols)
答案 1 :(得分:0)
您可以拥有一个“基础”视图控制器,例如BaseViewController。该控制器中将包含任何特定于日期选择器的代码。然后,所有相关的视图控制器将成为该基本控制器的子类。根据每个控制器的需要自定义行为,但每个控制器仍然有基本的选择器处理代码。如果您对所有这些控制器使用单个nib,请确保将“File's Owner”对象类设置为BaseViewController。所有子类仍然可以正常访问nib。