为什么要继承NSObject?

时间:2009-10-19 11:58:23

标签: objective-c inheritance nsobject

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

@interface Fraction : NSObject 

在C ++或Java中,我们不使用任何变量,如NSObject,即使我们在Objective-C和Java中都有预处理程序指令和import语句。

为什么类在Objective-C中明确地从NSObject继承?不从NSObject声明继承有什么后果?

5 个答案:

答案 0 :(得分:27)

我们使用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);
}

答案 1 :(得分:14)

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

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

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

答案 2 :(得分:6)

所有类都不一定从NSObject继承,但它是许多类的核心,因为它提供了诸如alloc,retain和release之类的东西。

答案 3 :(得分:1)

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

Objective-C是关于向其他对象发送消息的对象 - 因此存在NSObject以提供该基本功能。

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

选择一个类(比如NSString,或任何类似的东西),然后按照它的超类回到NSObject,看看每个类添加了什么功能,这可能是一个很有用的练习。

希望有帮助...

答案 4 :(得分:0)

  

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),则出现以下错误:

  

Class' ClassWithoutBaseClass'在没有指定基类的情况下定义