NOTE
Swift classes do not inherit from a universal base class. Classes you
define without specifying a superclass automatically become base
classes for you to build upon.”Excerpt From: Apple Inc. “07000” iBooks.
这对我来说没有什么意义。有一个原因为什么Objective-C有一个通用的基类,同样的原因应该适用于Swift,是吗? NSObject管理retain / release语义,isEqual:,hash和描述的默认实现。所有这些功能在Swift中也可用。
(Objective-C和Swift使用相同的运行时…)
所以,怎么了?是Swift类没有定义的超类只是NSObjects在引擎盖下作为适当的根类?或者是每个新的根类的默认对象行为重复?还是他们创建了另一个Swift基础类? retain和release的实现非常复杂,因为它需要同时考虑多线程和弱引用。
是否可能有一个通用的基类在Swift(尽管文档说)。这将是真的很方便,因为在Objective-C我可以写扩展,让我合并方法调用到主runloop像[obj.eventually updateCounter],可以读为“call -updateCounter下次主runloop控制。如果,在此期间,我再次调用此方法,使用这个扩展可以实现 – [UIView setNeedsDisplay] as [self.eventually display];如果没有通用基类(或者也许是,谁知道的),这在Swift中不再可能? )
There is a reason why Objective-C has a universal base class
正如苏尔坦所说,这不是真的。在Objective-C中有多个根类,你可以通过简单地不指定超类来定义一个新的根类。正如Sulthan也提到的,Cocoa本身有几个根类,NSObject,NSProxy和Object(ObjC 1.0中Protocol的根类)。
原来的Objective-C语言是非常灵活的,有人可以在理论上来创建他自己的根类,并创建自己的框架,完全不同于Foundation,并使用完全不同于retain,release,alloc,dealloc等的方法。 ,甚至可以实现完全不同的内存管理方式,如果他想。这种灵活性是对裸Objective-C语言的惊人之处 – 它只是提供一个薄层,所有其他事情,如对象的创建和销毁,内存管理等,都可以由用户决定框架坐在上面。
但是,使用苹果的Objective-C 2.0和现代运行时,需要完成more work来创建自己的根类。加上ARC,为了在ARC中使用你的对象,你必须实现Cocoa的内存管理方法,如retain和release。此外,要在Cocoa集合中使用您的对象,您的类还必须实现像isEqual:和hash这样的东西。
因此,在现代Cocoa / Cocoa Touch开发中,对象通常必须至少实现一组基本的方法,这是NSObject协议中的方法。 Cocoa中的所有根类(NSObject,NSProxy)实现NSObject协议。
So,what’s up with that? Are Swift classes with no defined
superclasses just NSObjects that pose as proper root classes under the
hood? Or is the default object-behavIoUr duplicated for each new
root-class? Or have they created another Swift-baseclass?
这是一个很好的问题,你可以通过内省Objective-C运行时找出来。 Swift中的所有对象在某种意义上也是Objective-C对象,因为它们可以像Objective-C中的对象一样与Objective-C运行时一起使用。类的一些成员(未标记为@objc或动态的)可能对Objective-C不可见,但是否则Objective-C运行时的所有内省功能完全在纯Swift类的对象上工作。在Swift中定义的类看起来像Objective-C运行时的任何其他类,除了名称被破坏。
使用Objective-C运行时,你可以发现对于一个作为Swift中的根类的类,从Objective-C的角度来看,它实际上有一个名为SwiftObject的超类。这个SwiftObject类实现了NSObject协议的方法,如retain,release,isEqual :,responsesToSelector:等(尽管它实际上不符合NSObject协议)。这是如何使用纯Swift对象与Cocoa API没有问题。
然而,从Swift本身,编译器不相信Swift根类实现这些方法。所以如果你定义一个根类Foo,那么如果你试图调用Foo()。isKindOfClass(Foo.self),它不会编译它抱怨这个方法不存在。但我们仍然可以使用它与一个技巧 – 回想一下,编译器将让我们调用任何Objective-C方法(编译器听说过)一个AnyObject类型的变量,方法查找产生一个隐式解包可选函数在运行时成功或失败。所以我们可以做的是转换为AnyObject,确保导入Foundation或ObjectiveC(所以声明对编译器可见),然后我们可以调用它,它将在运行时工作:
(Foo() as AnyObject).isKindOfClass(Foo.self)
所以基本上,从Objective-C的角度来看,一个Swift类或者有一个现有的Objective-C类作为根类(如果它继承自一个Objective-C类),或者有SwiftObject作为根类。