Как я могу динамически создать NSMutableArray с низкоуровневыми API времени выполнения? - PullRequest
1 голос
/ 09 июля 2011

Введение

Итак, я экспериментировал с низкоуровневыми API-интерфейсами Objective-C, определенными в <objc/runtime.h и следуя документации Apple . Вы можете увидеть результаты моей игры в этой истории .

Задача

Мне удалось динамически создать простой Hello World с помощью Objective-C только с помощью низкоуровневых API-интерфейсов времени выполнения и C (см. Суть выше). Оно работает. Сейчас я пытаюсь динамически создать 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.

Любой свет, пролитый на это, был бы очень признателен. Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 09 июля 2011

Я просто наткнулся на обходной путь, который ... работает ... Я обновил суть, чтобы показать, что он работает ...

По сути, вместо вызова class_createInstance вы явно отправляете сообщение alloc объекту класса NSMutableArray. Это работает:

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

Что заставляет нас задуматься: какой смысл class_createInstance тогда (я создаю новый SO поток для этого ...)?

0 голосов
/ 09 июля 2011

Не знаю точно, но я подозреваю, что Apple использует магию во время выполнения, чтобы переключиться на определенный подкласс, используя магию. Бьюсь об заклад, NSMutableArray, хотя видимое имя не является реальной реализацией. В прошлом были и другие подобные случаи.

...