【问题标题】:How can I dynamically create an NSMutableArray with the low-level runtime APIs?如何使用低级运行时 API 动态创建 NSMutableArray?
【发布时间】:2011-07-09 05:43:52
【问题描述】:

简介

所以我一直在试验 <objc/runtime.h 中定义的 Objective-C 低级运行时 API,并遵循 Apple's documentation。你可以看到我玩in this gist的结果。

问题

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

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]!'

但如果我将上面的 sn-p 的中间部分更改为:

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

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

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

【问题讨论】:

    标签: reflection nsmutablearray objective-c-runtime


    【解决方案1】:

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

    【讨论】:

    • 是的,毫无疑问,苹果公司在幕后施展了一些魔法。我想我更多的是在寻找解决方案/解决方法,而不是 why...
    【解决方案2】:

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

    基本上,您无需调用class_createInstance,而是将alloc 消息显式发送到NSMutableArray 类对象。这有效:

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

    这让我们想知道:那么class_createInstance 有什么意义(我正在为那个创建一个新的 SO 线程......)?

    【讨论】:

      猜你喜欢
      • 2019-06-30
      • 1970-01-01
      • 2013-09-09
      • 1970-01-01
      • 1970-01-01
      • 2020-06-05
      • 2010-09-11
      • 2017-06-25
      • 2017-12-28
      相关资源
      最近更新 更多