Метакласс и категория iOS / Objective-C

Я понимаю, что класс на самом деле является объектом / typedef структуры (objc_class*). Каждый класс имеет «поддерживающий» метакласс, который, в свою очередь, имеет указатель isa, указывающий на метакласс NSObject.

И NSObjectв основном имеет указатель isa, указывающий на себя.

И мы могли бы получить доступ к метаклассу через эту строку:

objc_getMetaClass("<CLASS_NAME>");

Я надеюсь, что мое понимание метакласса здесь еще не упущено (пожалуйста, поправьте меня, если это так).

Мои вопросы:

1.)

Когда нам нужно иметь дело с метаклассом? Не могли бы вы привести пример/сценарий в коде, когда нам это может понадобиться?

2.)

Предыстория:

Я свободно думал о сторонних библиотеках и о том, как они структурированы.

Обычно они предоставляют вам метод класса и возвращают вам класс, а все остальные методы являются закрытыми/скрытыми. И в большинстве случаев, хотя они могут быть подклассами, но, поскольку мы не знаем метод init, было бы бесполезно создавать подклассы.

И вдруг я начал думать о категории Objective-C, что привело меня к мысли о метаклассе Objective-C.

И это приводит к моему вопросу № 2:

Можно ли сломать эту структуру, используя категорию Objective-C и/или используя метакласс (взяв его и вставив метод класса прям там в мета классе)? Или даже посмотреть имя их методов экземпляра, которые являются закрытыми?

Мое намерение здесь состоит не в том, чтобы что-то «сломать», мне просто очень любопытно, насколько «нерушимы» эти сторонние библиотеки, и нельзя ли их структуры «сломать» с помощью Category и Метакласс.

@Лео Натан:

1.)

Что такое method_*()?

2.)

Из любви к среде выполнения Objective-C:

Не могли бы вы привести пример реализации метода экземпляра, скажем,

(Я не уверен, что этот метод является хорошим примером, потому что мы могли бы переопределить его в первую очередь)

Метод экземпляра NSArray -count (давайте сделаем так, чтобы он всегда возвращал значение 100, например)

3.)

Итак, теоретически все классы (включая все сторонние библиотеки) могут быть сломаны (сломаны)? Другими словами, нельзя создать API/библиотеку типа "вызов-только-этот-класс-метод-или-вы-не-можете-использовать-меня"?

Большое спасибо.


person Unheilig    schedule 30.12.2013    source источник
comment
Небольшое предложение: если вашей целью является внедрение или перечисление методов сторонних библиотек ObjC, вы можете просто использовать объективную среду выполнения c ;-) developer.apple.com/library/mac/documentation/cocoa/Reference/   -  person LombaX    schedule 30.12.2013
comment
@LombaX Спасибо за информацию - я не знал, что это возможно с использованием Objective-C Runtime. ;-) Опять же, я не пытаюсь что-то сломать - я действительно хочу узнать больше о том, что я упомянул в своем посте, и если когда-нибудь придет моя очередь создать стороннюю библиотеку/API, я мог бы сделать приличную сначала зная, как они / их структуры могут быть сломаны. Еще раз спасибо. Обязательно прочту еще и про Objective-C Runtime.   -  person Unheilig    schedule 30.12.2013


Ответы (1)


Метакласс полезен, когда вы хотите просмотреть, добавить или изменить методы класса и информацию на уровне класса.

Например,

    IMP myIMP = imp_implementationWithBlock(^(id _self, NSString *string) {
        NSLog(@"Hello %@", string);
    });
    Class cls = objc_getMetaClass("NSString");
    class_addMethod(cls, @selector(test:), myIMP, "v@:@");
    [NSString test:@"lala"];

Чтобы получить методы экземпляра, вы используете class_copyMethodList() для класса, возвращаемого методом class для объекта, или NSClassFromString(). Вы получите массив всех методов экземпляра, определенных классом (но не его суперклассом!). Затем вы можете использовать различные методы method_*() для получения информации и, возможно, даже модифицировать эти методы (например, изменение реализации).

Вы можете вызвать class_copyMethodList() в метаклассе, чтобы определить все методы класса.

Чтобы ответить на ваши вопросы о Льве,

1. Прочтите Справочник по среде выполнения Objective C. Вы можете найти раздел method_ функций, связанных с Method структурами.

2. См. руководство по реализации swizzling.

3. При использовании Objective C все доступно для среды выполнения. Само собой разумеется, что с большой силой приходит большая ответственность. Среда выполнения Objective C очень мощная. Эти напитки очень опасны и обычно не рекомендуются.

person Leo Natan    schedule 30.12.2013
comment
@Dvole Среда выполнения Objective C очень интересна! :-) - person Leo Natan; 30.12.2013
comment
@LeoNatan +1 Не только очень интересно, но и очень-очень интересно. У меня все еще есть некоторые проблемы с пониманием того, что вы упомянули (извините), я обновлю свой вопрос, сообщив вам, я надеюсь, что вы могли бы еще больше пролить свет на них. Заранее спасибо. - person Unheilig; 30.12.2013
comment
очень хорошо! логично, но никогда не использовал это так. круто видеть это - person Daij-Djan; 30.12.2013
comment
@LeoNatan Супер.. ах, еще одна вещь, этот аватар на сайте swizzling не вы (ваш ТАКОЙ аватар выглядит примерно так же, отсюда и мой вопрос), верно? :-) Просто любопытство. Отметит это как ответ. Спасибо! - person Unheilig; 30.12.2013
comment
@Unheilig Не я. :-) - person Leo Natan; 30.12.2013