Во время выполнения просто создать копию MyNSObject класса NSObject:
Сначала создайте новую пару .
Class MyNSObject = objc_allocateClassPair(nil, "MyNSObject", 0);
Второе прочитайте методы, протоколы и ivars из NSObject и добавьте их в новый класс.
uint instanceMethodCount;
Method *instanceMethodArray = class_copyMethodList([NSObject class], &instanceMethodCount);
for (int i = 0; i < instanceMethodCount; i++) {
Method method = *(instanceMethodArray + i);
SEL selector = method_getName(method);
IMP implementation = method_getImplementation(method);
const char *types = method_getTypeEncoding(method);
BOOL success = class_addMethod(MyNSObject, selector, implementation, types);
}
free(instanceMethodArray);
uint protocolCount;
Protocol **protocolArray = class_copyProtocolList([NSObject class], &protocolCount);
for (int i = 0; i < protocolCount; i++) {
Protocol *protocol = *(protocolArray + i);
BOOL success = class_addProtocol(MyNSObject, protocol);
}
free(protocolArray);
uint ivarCount;
Ivar *ivarArray = class_copyIvarList([NSObject class], &ivarCount);
for (int i = 0; i < ivarCount; i++) {
Ivar ivar = *(ivarArray + i);
const char *name = ivar_getName(ivar);
const char *typeEncoding = ivar_getTypeEncoding(ivar);
NSUInteger size, alignment;
NSGetSizeAndAlignment(typeEncoding, &size, &alignment);
BOOL success = class_addIvar(MyNSObject, name, size, alignment, typeEncoding);
}
free (ivarArray);
В-третьих, прочитайте методы из метакласса NSObject и добавьте их в новый метакласс.
uint classMethodCount;
Method *classMethodArray = class_copyMethodList(object_getClass([NSObject class]), &classMethodCount);
for (int i = 0; i < classMethodCount; i++) {
Method method = *(classMethodArray + i);
SEL selector = method_getName(method);
IMP implementation = method_getImplementation(method);
const char *types = method_getTypeEncoding(method);
BOOL success = class_addMethod(object_getClass(MyNSObject), selector, implementation, types);
}
free(classMethodArray);
И, наконец, зарегистрируйте пару классов.
objc_registerClassPair(MyNSObject);
Ну, это почти так просто. Есть пара проблем с этим. Ну, пара пар. Если бы мы добавили следующие строки в конец, но в пределах первого для блока
if (!success) {
NSLog(@"unable to add method with selector named %@ to class MyNSObject", NSStringFromSelector(selector));
}
и следующие строки в конце, но в течение последнего для блока
if (!success) {
NSLog(@"unable to add method with selector name %@ to metaclass MyNSObject", NSStringFromSelector(selector));
}
Затем мы увидим следующий вывод:
unable to add method with selector name retainWeakReference to class MyNSObject
unable to add method with selector name allowsWeakReference to class MyNSObject
unable to add method with selector name load to metaclass MyNSObject
unable to add method with selector name initialize to metaclass MyNSObject
Что здесь происходит? Выполняют ли классы (соответственно метаклассы) keepWeakReference и позволяют WeakReferenc (соответственно загрузить и инициализировать) "из коробки"?
Литература:
1. Cocoa с любовью - Что такое метакласс в Objective-C?
2. Переполнение стека - ответ Justin Spahr-Summers на "Как получить размер sizeof, для которого есть кодировка?"