高效使用 Interface Builder

3

我是新手,对iPhone和Objective-C都不熟悉。我花了很多时间阅读文档并尝试理解它们的工作原理。我已经阅读了FM(至少正在阅读)。

我的主要问题是我想了解如何指定事件传递到哪里,而我唯一能做到的方式是指定委托,但我确信在IB中有更简单/更快捷的方法。

所以,举个例子。 假设我有20个不同的视图和视图控制器以及一个MyAppDelegate。 我想能够在IB中构建所有这些不同的Xib文件,并添加任意数量的按钮、文本字段和其他内容,然后指定它们在MyAppDelegate对象中产生某些事件。为此,在IB的列表视图中的每个视图控制器中添加了一个MyAppDelegate对象。然后我在XCode中创建了一个MyAppDelegate的IBAction方法,然后返回IB并将所有的事件链接到每个Xib文件中的MyAppDelegate对象。

然而,当我尝试运行它时,它只是崩溃并出现错误读取异常。

我猜测每个Xib文件都会放置一个MyAppDelegate对象指针,这个指针与最终在运行时实际创建的MyAppDelegate地址无关。

那么我的问题是...我该怎么做?!!!

3个回答

4
如果您在每个nib文件中创建MyAppDelegate的实例,那么当所有nibs加载时,确实会得到许多不同的类实例。应用程序委托并不是通过类或协议来标识,而是通过被应用程序实例的delegate属性所指向的对象来标识。要找到真正的应用程序委托,您必须询问应用程序对象本身的委托。
您应该让所有的视图控制器都从一个具有appDelegate属性的父视图控制器类继承。实现类似下面的内容:
#import "MyAppDelegateClass.h"

@interface ViewControllerBaseClass :UIViewController {
    MyAppDelegateClass *appDelegate;
}
@property(nonatomic, retain)  *appDelegate;

@end

@implementation ViewControllerBaseClass
@synthesize appDelegate;

-(MyAppDelegateClass *) appDelegate{
    self.appDelegate=(MyAppDelegateClass *)[[UIApplication sharedInstance] delegate];
    return appDelegate;
}
@end

当视图控制器需要应用程序委托时,只需调用self.appDelegate。如果您想访问应用程序委托的属性,请使用self.appDelegate.attributeName

重要的是,在运行时向应用程序请求其特定的委托实例。您无法从nib文件中执行此操作。


如果我说@property (nonatomic,retain) IBOutlet MyAppDelegateClass *appDelegate,然后从这个基础Viewcontroller子类化我的每一个视图控制器,然后在我的AppDelegate本身中添加各种IBAction方法,那么肯定有一种方法可以连接那些IBOutlets在界面构建器中而不是在代码中吗?到目前为止,我已经通过在MyAppDelegateClass内部从加载视图控制器时将appDelegate属性设置为self来以编程方式完成了它,但我认为[UIApplication ...]行会更好。但是在IB中没有一种方法吗? - twerdster
1
应用程序委托是一个特定的实例。您必须指向该特定实例,否则您将无法到达实际的委托。仅仅给一个类一个出口并不能让它的子类指向一个特定的实例。每个出口都必须链接到应用程序对象使用作为其委托的特定应用程序委托实例。 - TechZen
1
Nib文件旨在具有模块化和受限范围。按设计,它们不依赖于整个应用程序甚至应用程序对象。因此,只有应用程序对象本身拥有的nib(通常是MainWindo.nib)才能看到活动委托。 - TechZen
1
如果想在IB中连接它,您可以创建一个小实用类,其功能是查找活动的应用代理实例。然后,您可以将该类添加到任何随机nib中,并将出口连接到该类。这将使您能够在不使用子类化的情况下管理nibs中对应用程序代理的访问。 - TechZen
好的,非常棒的回答。非常感谢您的时间和高效的回复。 - twerdster

1

我不太清楚你具体想做什么,但这可能是一个坏主意。每个应用程序只应该有一个应用委托,并且它应该处理整个应用程序的行为。通常,应用委托初始化根视图控制器并显示它们,但除了处理打开和保存数据源之类的事情外,没有太多其他工作。

视图控制器(UIViewController的子类)应该与XIB进行交互。在视图控制器中具有视图特定的行为使应用程序更易于管理和维护。通常,每个视图控制器应该有0或1个XIB(超过这个数量会变得复杂)。您可以使用Target/Action模式和IBOutlets和IBActions设置与视图的交互(请参见此处以获取完整指南)。通常,将视图控制器或XIB依赖于应用委托是一个坏主意(因为减少依赖关系可以使代码更易于管理)。


好的,那我换一个略微不同的问题。我该如何创建一个视图控制器来控制多个不同的视图,其中每个视图都在单独的nib文件中定义。假设我使用5个不同的nib构建了5个视图,除了视图之外,没有其他内容在nib层次结构中。现在我构建了一个nib,其中包含一个视图控制器但没有视图。我如何使用运行时指定的视图初始化MyAppViewController?UIView中是否有此选项?然后,我是否必须将每个仅包含视图的nib的文件所有者设置为MyAppViewController类型?或者应该如何完成它? - twerdster

0
通常情况下,您应该为每个视图构建一个视图控制器,并将事件链接到这些视图控制器上 - 而不是应用程序委托。事实上,即使在示例项目中,通常也没有任何事件从任何nib文件中连接到应用程序委托,您会注意到视图控制器是由应用程序委托创建并保存的,但它不接收事件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接