Intro
因此,我一直在尝试<objc/runtime.h
中定义的Objective-C低级运行时API,并遵循Apple的文档。你可以在这个要点中看到我的演奏结果。
问题
我已经能够通过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);
这让我有点困惑,因为它们应该是等效的。第一个代码片段应该等效于调用作为 Objective-C 语法工作的 [[NSMutableArray alloc] init]
,但在调用这些 C 函数时则不然。
对此的任何了解将不胜感激。提前感谢!
我不确定,但我怀疑苹果做了一些运行时魔术来交换特定的子类,做魔术。我敢打赌,NSMutableArray虽然是可见的名称,但并不是真正的实现。过去还有其他案例。
我只是偶然发现了一种解决方法...工程。。。我已经更新了要点以显示它正在工作...
基本上,不是调用 class_createInstance
,而是显式地向 NSMutableArray
类对象发送alloc
消息。这有效:
id array = objc_msgSend(nsmutablearray, sel_registerName("alloc"));
id arrayAfterInit = objc_msgSend(array, sel_registerName("init"));
这让我们想知道:那么class_createInstance
有什么意义(我正在为那个线程创建一个新的 SO 线程......