【问题标题】:Why subclass NSObject?为什么要继承 NSObject?
【发布时间】:2010-12-07 23:30:41
【问题描述】:

Objective-C 中 NSObject 的用途/用途是什么?我看到像这样扩展 NSObject 的类:

@interface Fraction : NSObject 

在 C++ 或 Java 中,我们不使用像 NSObject 这样的任何变量,即使我们在 Objective-C 和 Java 中都有预处理器指令和导入语句。

为什么类在 Objective-C 中显式继承自 NSObject?不声明继承自 NSObject 会有什么后果?

【问题讨论】:

    标签: objective-c inheritance nsobject


    【解决方案1】:

    我们使用 NSObject 来明确说明给定类继承自什么。我不确定 C++,但在 Java 中有类似的东西 - Object 类。唯一的区别是Java 不要求类显式 从Object 继承——该语言假定任何没有指定父类的东西都从Object 继承。 Objective-C 是不同的,因为它允许你定义不同的根类——你被允许创建一个不继承自 NSObject 的类。

    NSProxy 是此类不同根类的一个示例。

    看看GNUstep NSObject source,它展示了方法如何通过C函数与objective-c运行时交互。

    + (id) allocWithZone:(NSZone*)z
    {
      return NSAllocateObject(self, 0, z);
    }
    
    - (void) dealloc
    {
      NSDeallocateObject (self);
    }
    
    + (BOOL) isSubclassOfClass: (Class)aClass
    {
      return GSObjCIsKindOf(self, aClass);
    }
    

    【讨论】:

    【解决方案2】:

    由于面向对象的语言具有继承的概念,因此在任何继承层次结构中都有一个根类。在Java 中,默认父类(如果没有提供)是java.lang.Object,而在Objective-C 中,如果您没有显式声明父类,则不会得到。从本质上讲,您的类本身就是一个根类。这是 Objective-C 新手的常见错误,因为在这种情况下您通常希望从 NSObject 继承。

    虽然经常有问题和令人费解,但这实际上提供了相当多的灵活性,因为您可以定义自己的类层次结构,它们的行为与 NSObject 完全不同。 (Java 根本不允许您这样做。)另一方面,除非您知道自己在做什么,否则很容易让自己陷入困境。幸运的是,如果您调用的方法不是由没有声明父类的类定义的,例如您通常希望从 NSObject 继承的方法,编译器会提供警告。

    至于NSObject的“使用”,查看NSObject class和NSObject protocol的文档。它们定义了用于对象分配、内存管理、比较、散列、打印描述、检查类成员资格、查询对象是否响应选择器等的常用方法。基本上,NSObject 是“有益于”提供 Objective-C 对象的核心功能免费。

    【讨论】:

      【解决方案3】:

      所有类不一定都继承自 NSObject,但它是许多类的核心,因为它提供了诸如分配、保留和释放之类的功能。

      【讨论】:

        【解决方案4】:

        NSObject 是所有类的根类。据我估计,它的 3 个最基本的功能是为您分配和初始化内存(alloc 和 init),以及提供描述功能。

        Objective-C 是关于对象向其他对象发送消息的全部内容——所以 NSObject 的存在就是为了提供基本功能。

        如果这对您来说听起来很奇怪,您可能希望阅读更多有关编程范式的信息,尤其是面向对象的编程......不过,简而言之,Objective C 是 C 语言的简单扩展。 C 使您能够对计算机内存、数字和字符进行编程,但是做其他任何事情(例如使用字符串或显示视图)都需要扩展部分,而 NSObject 是该扩展的开始。

        选择一个类(如 NSString 或任何其他类)可能是一个有用的练习,然后将它的超类返回到 NSObject,以查看每个类添加了哪些功能。

        希望对您有所帮助...

        【讨论】:

          【解决方案5】:

          NSObject

          大多数 Objective-C 类层次结构的根类,从中 子类继承了运行时系统的基本接口,并且 表现得像 Objective-C 对象的能力。

          来自 Apple 文档 - https://developer.apple.com/documentation/objectivec/nsobject。

          基本上,大多数 OOP 编程语言显式或隐式指定基类或基功能。否则,您无法构建对象相互通信的系统。属性、内存管理、消息发送机制部分或全部由 NSObject 提供或支持。 Apple 提供了部分 Objective-C 实现 - https://opensource.apple.com/source/objc4/objc4-723/runtime/NSObject.mm.auto.html,可以在其中查看 NSObject 中的实际内容。

          另外,因为 Objective-C 是 C 系列的语言,所以编译器和链接器需要计算如何在内存中布局对象以及放置和查找方法的位置,这只有在您知道每个类/实例的放置方式时才有可能在内存和哪里。在 Objective-C 的情况下,所有基类(NSObject、NSProxy 等)都有其规范,因此可以计算它们的大小并添加所有继承的东西 - https://clang.llvm.org/compatibility.html#objective-c。

          因此编译器不会让没有基类的类离开。所以最终类继承应该导致根类之一。如果您不指定它(来自 Xcode),则会出现以下错误:

          在未指定基类的情况下定义类“ClassWithoutBaseClass”

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-08-26
            • 2014-08-26
            • 1970-01-01
            • 2011-06-17
            • 1970-01-01
            • 2017-02-17
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多