1

介绍

所以我一直在尝试使用在Apple 文档<objc/runtime.h中定义并遵循的 Objective-C 低级运行时 API 。你可以在这个 gist中看到我演奏的结果。

问题

我已经能够通过 Objective-C 仅通过低级运行时 API 和 C 动态创建一个简单的 Hello World(参见上面的要点)。有用。现在我正在尝试NSMutableArray使用相同的技术动态创建一个。这是代码片段:

Class nsmutablearray = objc_getClass("NSMutableArray");

id array = class_createInstance(nsmutablearray, 0);
id arrayAfterInit = objc_msgSend(array, sel_registerName("init"));

// get the count
objc_msgSend(arrayAfterInit, sel_registerName("count"))

但这给了我一个错误:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSArray count]: method only defined for abstract class. Define -[NSMutableArray count]!'

但是,如果我将上面代码段的中间部分更改为:

id arrayAfterInit = objc_msgSend(nsmutablearray, sel_registerName("arrayWithCapacity:"), 10);

这让我有点困惑,因为它们应该是等价的。第一个片段应该等同于调用[[NSMutableArray alloc] init]作为 Objective-C 语法的调用,但不是在调用这些 C 函数时。

对此的任何启示将不胜感激。提前致谢!

4

2 回答 2

0

我不确定,但我怀疑 Apple 做了一些运行时魔法来交换特定的子类,做魔法。我敢打赌 NSMutableArray,虽然是可见的名称,但并不是真正的实现。过去还有其他类似的案例。

于 2011-07-09T05:51:27.833 回答
0

我只是偶然发现了一种解决方法...有效...我已经更新了要点以显示它有效...

基本上,您不是调用,而是显式地向Class 对象class_createInstance发送alloc消息。NSMutableArray这有效:

id array = objc_msgSend(nsmutablearray, sel_registerName("alloc"));
id arrayAfterInit = objc_msgSend(array, sel_registerName("init"));

Which makes we wonder: what's the point of class_createInstance then (I'm creating a new SO thread for that one...)?

于 2011-07-09T19:06:32.000 回答