【问题标题】:How to access a class from another class?如何从另一个类访问一个类?
【发布时间】:2011-04-06 22:55:17
【问题描述】:

我对 OO 还很陌生。如果我有两个类 A 和 B 需要交换数据,或者调用彼此的方法,我需要能够从类 A 访问 B 类的实例。我应该在全局变量中维护实例对象的地址吗?我应该指定一个(单例)主类,并创建(指向)主类的 A 和 B 属性的实例吗? (想到 AppDelegate。)

有没有一种简单的按书本的方法来实现这一点?不知何故,我在这里错过了一些“最佳实践”。我查看了 Apple 的示例,但没有找到答案。

编辑:由于我对 MVC 设计模式还很陌生,所以我的问题本质上是“谁创造了谁”?

我们在这里谈论的是音频播放器。 1. 当用户选择一首歌曲时,UI 通过创建一个 viewController 来显示其波形,该 viewController 创建适当的视图。 2. 当用户点击播放时,UI 会在歌曲播放时通过在波形上覆盖一个新视图来显示时间线。现在,后一个视图需要来自波形显示视图控制器的一些信息。现在,我将指向 viewController 的指针存储在我的 appDelegate 的实例变量中。这行得通,但感觉非常奇怪。

我是否应该将两个班级所需的信息外包给每个班级都可以轻松访问的第三方实体?

【问题讨论】:

    标签: objective-c cocoa oop


    【解决方案1】:

    类不仅仅是代码的部门。它们是用于创建对象的模板,您应该将其视为程序中的参与者,在其职责范围内做事(由您定义——您决定每个对象做什么)并相互交互。

    虽然您可以像处理对象一样处理类,但类通常不会相互通信。大多数时候,您将创建和使用类的实例——这就是我们通常所说的“对象”——并让它们相互交谈。一个对象向另一个对象发送消息,告诉接收者做某事或改变接收者的一个属性。这些消息是程序对象之间的交互。

    方括号中的那些奇怪的表达式是消息表达式。您对类或对象所做的几乎所有事情都会涉及一条或多条消息。您可以像向对象一样向类发送消息,而类也可以像向对象一样发送消息。

    在 Cocoa 和 Cocoa Touch 中,通常有模型对象、视图对象、控制器对象、数据对象(例如 NSString、NS/UIImage 和 NSURL)和辅助对象(例如 NSFileManager)。您将为应用程序编写的类主要是模型、视图和控制器对象 (MVC)。模型代表(模型)用户将看到自己在操作什么;视图向用户显示模型;控制器实现逻辑并确保模型被保存到持久存储并从持久存储中加载。

    有关详细信息,请参阅Object-Oriented Programming in Objective-CCocoa Fundamentals Guide

    由于我对 MVC 设计模式还很陌生,所以我的问题本质上是“谁创造了谁”?

    控制器创建和加载模型,加载视图,并将模型传递给视图进行显示。某些控制器也可以创建其他控制器。

    最好保留一个简单的树状所有权图,从程序的单个根(通常是应用程序对象)向下通过控制器到模型和视图中的叶对象。如果两个对象相互拥有,那就是个问题。如果一个对象不属于它自己的类(单例)之外的任何东西,这通常也是一个问题——这表明您需要更多地考虑该代码所属的位置。 (Helper 对象是主要的例外;其中大多数是单例。再次,请参阅 NSFileManager 的示例。但它们很少而且相差甚远。)

    【讨论】:

    • 哇,感谢您的澄清。回到我手头的问题,你的意思是,我的模型和我的观点首先不应该相互交谈?一切都应该通过控制器调度。
    • @Joe Völker:正确。当使用标准视图时,控制器应该将数据对象从模型传递到视图并返回。使用自定义视图时,我通常会为自定义视图提供一个属性,以便模型对象显示和编辑。不同之处在于标准视图被设计为通用的,几乎可以与任何应用程序中的任何模型一起使用,而我将为特定模型设计自定义视图。模型从不与视图对话,应该尽可能少地和一般地与控制器对话。
    【解决方案2】:

    进一步的情况分析需要更多信息。首先,您应该更多地指定类之间的关系以及交换数据的确切含义。

    通常应避免单身人士。如果您想交换信息,通常通过某种方法或构造函数将类 A 的实例提供给类 B 的实例就足够了。然后 B 的实例能够调用 A 实例的公共方法(并访问公共属性)。

    可以通过搜索“设计模式”来学习一些“最佳实践”。

    【讨论】:

    • 更多信息:我的主视图的两个子视图代表我的数据。一个是显示波形,另一个是显示在其上移动的时间线。他们需要访问一些通用数据。现在,子视图在需要时被实例化并创建自己的表示,即,波形视图类在其 drawRect: 中从音频数据创建波形图形。
    • 我认为这取决于常用数据的类型。如果它们与输入数据相关,我将创建表示数据的不同对象并将其提供给两个视图。如果它与视图本身有关,也许您可​​以将两个视图包装到一个容器中,或者以不同的方式将它们统一起来。或者也许你会带来更聪明的东西......
    【解决方案3】:

    您应该决定一个类是否可以是另一个类的对象(封装),或者一个类是否可以从另一个类继承(继承)。如果这些都不是一个选项,那么也许您可以将一个类(或其某些成员)设为静态?

    【讨论】:

      【解决方案4】:

      感谢您的贡献。此外,我发现this page 上的信息非常有用。它以动手实践的方式和实用的语言列出了可可的 MCV 考虑因素。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-18
        • 2017-01-03
        • 1970-01-01
        • 1970-01-01
        • 2021-12-29
        • 2012-01-04
        • 2012-05-06
        相关资源
        最近更新 更多