如果你不能先调用 [super init] 怎么办

What if you cant invoke [super init] first

我正在尝试对 UIPopoverController 进行子类化,并赋予 IT 确定要创建和呈现哪种 UIViewController (contentViewController) 的适当责任,而不是将弹出窗口的调用代码与该责任搞得一团糟。但是我 运行 遇到了几个问题。

根据 Apple 文档,在第一次调用之前没有正当理由做任何事情。

if (self = [super init])

所以我尝试了那个,认为我可以在稍后的方法中简单地设置 contentViewController 属性 当我的代码检查我传入的数据并决定创建哪个 UIViewController 和prsent,但是调用 [super init] 时出现错误,告诉我必须调用另一个初始化程序。

[super initWithContentViewController:...]

所以我的问题如下图所示。我不能使用自定义初始化程序的第一行来做出决定,然后在对 super 的调用应该是第一个调用时调用 super 并且根据苹果的说法,没有充分的理由不让它成为第一个打电话。

initWithData:(MyDataObject*)data
   // examine data object and determine what kind
   // of UIViewController to create and present
   //
   // [super initWithContentViewController:myDecidedContentViewController

怎么办? 谢谢。

Apple documentationUIPopoverController

When initializing an instance of this class, you must specify the view controller that provides the content for the popover.

UIPopoverController 本身没有任何内容,它需要另一个 UIViewController 来呈现您真正想要呈现的内容。 UIViewController 的任何 subclass 都可以,只要它不与 popover 控制器冲突。

例如,您可以使用来自 StoryboardXIB 的自定义设计的控制器,或以编程方式实例化的 UIViewController。但是,您不仅限于这两个。 Subclassing UIPopoverController 无济于事,因为 subclass 仍然需要一个内容控制器。

现在,subclassing UIPopoverController 并在 class 中实现创建内容控制器的逻辑违反了 Single Responsibility Principle混合弹出窗口的职责 class。目前 UIPopoverController 有一个很好的责任 - 在弹出窗口中显示视图控制器,如果你还让它负责创建内容控制器,你只会增加它的负担。

我的建议是创建一个 MyPopoverFactory class,它具有创建弹出窗口及其内容控制器的方法。例如:

- (UIPopoverController*)popoverForSomething

我不知道,这是否有帮助,因为我真的不明白,你必须做出什么决定。但是在这种情况下你可以使用的一般模式(它类似于 class 集群)是有另一个创建者。 (你也可以用 -init… 做到这一点,但这很不方便。如果你需要它,请告诉我。)

+ (instancetype)myPopUpControllerForData:(id)data
{
    // make the decision on data
    Class contentViewControllerType;
    contenViweControllerType = …; 

    // After that create the instance of the content view controller
    contentViewController = [[ContentViewControllerType alloc] init…];

    // init… is the first message after alloction
    self = [[self alloc] initWithContentViewController:contentViewController];

    return self;
}

文档只要求 -init… 是分配实例的第一条消息。这并不意味着您失去了使用 运行 与 该实例 .

相关的代码的自由