【问题标题】:Objective C communication between classes类之间的Objective C通信
【发布时间】:2010-12-29 16:14:39
【问题描述】:

我有一个 AppController 类,它以通常的方式在我的应用中处理视图/控件。

在 IB 中我的应用程序主窗口上有一个按钮,它导致 AppController 实例化一个新窗口控制器 (accountPanelController) 并显示该辅助窗口:

- (IBAction) showAccountPanel:(id) sender
{
    //Is accountController nil?
    if (!accountPanelController) {
        accountPanelController = [[AccountPanelController alloc] init];
    }

    [accountPanelController showWindow:self];
}

当新窗口完成后,我想将从辅助窗口控制器收集的数据发送到 AppController 中的一个方法:

- (IBAction) close: (id) sender
{
    NSLog(@"Close detected");
    [AppController addAccount:0];
    [self close];
}

但是,当我尝试从新窗口控制器调用 AppController 中的 addAccount 方法时,我收到“'AppController' 可能无法响应 '+addAccount'”警告。

这似乎与 AppController 是一个类而不是对象实例化有关,因为 AppController 中的方法称为 -addAccount(而不是警告中报告的 +addAccount)。实际上,如果我将目标方法的名称更改为 +addAccount 而不是 -addAccount,则不会出现警告(但程序在执行时崩溃)。

鉴于我自己实际上并没有实例化 AppController(我猜在 NIB 启动期间会以某种方式发生),有没有人知道如何将数据发送到 AppController 方法?通知似乎有点矫枉过正......

非常感谢。

【问题讨论】:

    标签: objective-c class methods


    【解决方案1】:

    我推荐以下苹果 Mac 开发中心的介绍文章:Communicate with Objects - #Notifications
    更新
    我将链接指向相关锚点(通知)。

    您的代码示例中的问题是,您调用了一个类方法(带有 + 的方法),但您实现了一个实例方法 (-)。
    所以一个简单的解决方法是,获取AppController 的(共享)实例(可能是代码中的self)并将addAccount: 消息发送给它。
    但我鼓励你先阅读这篇文章。

    也许您可以通过从您的视图向控制器发送通知 (NSNotification) 来解决您的问题。

    更新:
    另一个有趣的读物可能是this SO question regarding the difference between class methods and instance methods

    【讨论】:

    • 非常感谢。我阅读了所有链接。根本原因是 AppController 是一个我没有实例化但 IBuilder 指向 (IBAction) 的类。所以我没有办法指向 AppController 在实例化时产生的实例。通知工作。有没有更简单的方法?甚至 Hillegass 在他关于面板的章节中也使用了通知。人们必须从许多应用程序中的 2ary 窗口获取数据,所以这一定很常见?我不熟悉共享实例,并努力寻找一些文档。你知道任何可能有帮助的吗?如下,我试过 [self addAccount] 没有运气。再次感谢。
    • 您可能可以使用 [NSApplication sharedApplication],它是应用程序委托的共享实例。但我认为在这里使用通知是正确的做法。
    【解决方案2】:

    只需提供一个 intiWithOtherController 方法并将其添加到此处:

    accountPanelController = [[AccountPanelController alloc] initWithOtherController:self];
    

    只是传递自我,所以你需要这样的东西:

    (AccountPanelController *) initWithOtherController:(OtherController *) 
    

    现在你有一个指向 otherController 的指针,你可以这样做:

    [otherController addAccount:0]
    

    【讨论】:

    • 得到这个工作。很好很简单。谢谢。一旦 initWithOtherController 返回,唯一的问题就是以某种方式保持 otherController 指针,以便我可以在 Window 的 close 方法中使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多