Objective c 为什么objc“U duplicateClass标记为”;不要自己调用此函数;

Objective c 为什么objc“U duplicateClass标记为”;不要自己调用此函数;,objective-c,Objective C,forobjc\u duplicate类 用于基金会的关键值观察。不要自己调用这个函数 没有详细说明或解释。我读了这本书,但除了一些理论之外,没有看到任何东西能让我明白为什么你不应该叫它;除了load和initialize没有为objc\u duplicateClass创建的类调用之外 通过调用objc\u allocateClassPair而不使用额外的字节来增加额外的IVAR,然后立即注册它,似乎可以产生几乎相同的效果。那么,objc\u duplicateClass有什么特别之处呢?或者,

for
objc\u duplicate类

用于基金会的关键值观察。不要自己调用这个函数

没有详细说明或解释。我读了这本书,但除了一些理论之外,没有看到任何东西能让我明白为什么你不应该叫它;除了
load
initialize
没有为
objc\u duplicateClass
创建的类调用之外


通过调用
objc\u allocateClassPair
而不使用额外的字节来增加额外的IVAR,然后立即注册它,似乎可以产生几乎相同的效果。那么,
objc\u duplicateClass
有什么特别之处呢?或者,换一种说法,如果假设我想在objc运行时之上构建KVO或类似的东西,那么使用
objc\u duplicateClass

是否安全?即使我将Q标记为基于意见,我还是想尝试一个答案:

A.这样的语句通常将某个函数(或任何函数)标记为已过时,并计划在将来删除

B.事实上,没有理由这样做。我不同意你的说法,注册一个没有额外字节的新类就可以了。因为可能有额外的字节,您必须手动复制所有实例变量描述和方法

然而,过去我不得不处理KVO这样的情况。我从未使用过
objc_duplicateClass()
,因为创建一个子类然后使实例成为该子类的成员要容易得多,而且类似于cleaner。您可以为该调用
对象\u setClass(id对象,Class cls)
执行isa swizzling

想想一种情况,显然是你的,另一种技术也想做类似KVO的事情。使用
objc_duplicateClass()
复制一个类不涉及原始类将来的动态更改。可能会添加一个方法。复制也不会添加此方法


因此,
objc\u duplicateClass()
是没有用的,也是一种不好的方法。

objc\u duplicateClass
做了它在tin上所说的事情:它生成一个新的类,它是您给它的类的副本。这包括复制旧类拥有的方法、所有元数据位甚至元类

您无法使用
objc\u allocateClassPair
重新创建此行为,因为
objc\u allocateClassPair
为您创建的类注册一个新的元类,以及初始化该类等其他事情-它意味着创建一个新类
objc_duplicate类
创建一个副本;“new”类不再初始化,也不会得到新的元类,因为原来的元类已经初始化了


至于为什么
objc_duplicateClass是这样记录的:不鼓励使用它
objc_duplicateClass
有一些罕见的用例,而且几乎永远不会是您想要的。如果您发现有必要使用它,请使用它,但请记住,该实现可能有一些您可能不知道的细节。

您不应该使用它,因为它是一个可以更改或删除的内部函数。@Sulthan它不是内部函数,因为它是有文档记录的。然而,系统libs的每一种方法或功能都可能改变。我认为“没有理由使用这个功能”是不对的。它的存在是有原因的——准确地复制一个类。@Itafferber没有理由像我在文章中解释的那样复制一个类。仅仅因为你不必这样做并不意味着这样做没有好处。通过分配一个新类并调用
object\u setClass
,任何查看该对象类的人都可以看到该新类。例如,使用
-isMemberOfClass:
的任何人都会被打断。这两种方法都有缺点,但都不一定是“正确的”。对类的动态更改不通过复制的类反映也是不正确的——它们确实反映了,而且运行时足够聪明,可以转发这些更改。您可以自己测试:将一个方法添加到一个现在观察到的对象的原始类中,然后对具有重复类的对象调用该方法。这是错误的:从外面可以看到观察一个类。只需尝试获取类名:使用
class\u getName(object\u getClass(object))
nskvonitifying\u className
。即使它是复制的,它也是一个新类
isMemberOfClass:
是一种方法,很容易被子类覆盖。您能举个例子,在哪种罕见的用例中需要使用该函数,以及具体的细节是什么?@Aminegm Awad最突出的用例是KVO,这就是它存在的原因。向对象添加观察者时,KVO复制该类并更改对象的isa以指向复制的类。所有现有的方法都通过现有的分派表进行转发,但是任何观察到的属性都可以在此类副本中更改它们的实现,而不会影响旧的“real”类。这比生成一个新类(todo和分派方法调用)要快得多,并且不会破坏兼容性,因为新类在大多数情况下都是旧类。您不必这样做-这里没有必要。但是,无声地复制类可以在最小破坏的情况下实现高效的实现……我不明白,为什么这会显著加快,因为创建一个几乎为空的新类会减少创建类时要做的工作。此外,用于调度的方法将以极快的速度存储在缓存中。更改的实现只是子类中被覆盖的实现。(在这两种情况下,您都必须调用基本实现。)对于观察到的属性,分派是不相关的,因为即使为observer方法创建对象的成本也会高得令人难以置信