Переопределить метод через категорию ObjC и вызвать реализацию по умолчанию?

При использовании категорий вы можете переопределить методы реализации своими собственными, например:

// Base Class 
@interface ClassA : NSObject 
- (NSString *) myMethod;
@end
@implementation ClassA
- (NSString*) myMethod { return @"A"; }
@end

//Category
@interface ClassA (CategoryB) 
- (NSString *) myMethod;
@end
@implementation ClassA (CategoryB)
- (NSString*) myMethod { return @"B"; }
@end

Вызов метода «myMethod» после включения категории категории результат "B".

Какой самый простой способ для реализации категории myMethod в категории вызвать исходный myMethod класса A? Насколько я могу понять, вы должны использовать низкоуровневые вызовы, чтобы получить исходный метод для класса A и вызвать его, но казалось, что синтаксически будет проще сделать это.

Ответы на вопрос(4)

найденном в библиотеке разработчика Mac: http://codeshaker.blogspot.com/2012/01/calling-original-overridden-method-from.html

По сути, это то же самое, что и описанный выше метод Swizzling с кратким примером:

#import <objc/runtime.h>

@implementation Test (Logging)

- (NSUInteger)logLength {
    NSUInteger length = [self logLength];
    NSLog(@"Logging: %d", length);
    return length;
}

+ (void)load {
    method_exchangeImplementations(class_getInstanceMethod(self, @selector(length)), class_getInstanceMethod(self, @selector(logLength)));
}

@end

ConciseKitвы на самом деле вызываете реализацию по умолчанию & # x2026;weirdly enough.. вызывая вашу реализацию SWIZZLED ..

Вы настроили это в+ (void) loadзвонит+ (BOOL)swizzleMethod:(SEL)originalSelector with:(SEL)anotherSelector in:(Class)klass;т.е.

[$ swizzleMethod:@selector(oldTired:) 
            with:@selector(swizzledHotness:) in:self.class];

и затем в методе swizzled ... предположим, что он возвращается-(id).. вы можете нанести вред, или по какой-либо другой причине, по которой вы черпаете в первую очередь & # x2026; а затем, вместо возврата объекта, илиselfили еще много чего ..

return [self swizzledHotness:yourSwizzledMethodsArgument];

Как объяснено здесь & # x2026;

In this method, it looks like we're calling the same method again, causing and endless recursion. But by the time this line is reached the two method have been swapped. So when we call swizzled_synchronize we're actually calling the original method.

Это выглядит и выглядит странно, но .. это работает. Это позволяет добавлять бесконечные украшения к существующим методам, и при этом «вызывать супер» (на самом деле самостоятельно) и пожинать плоды ручной работы оригинального метода & # x2026; даже без доступа к первоисточнику.

Решение Вопроса

включающий в себя использование среды выполнения target-c, вы всегда можете использоватьметод метания (вставьте стандартные отказы от ответственности здесь.) Это позволит вам сохранить различные методы как произвольно названные селекторы, а затем поменять их во время выполнения по мере необходимости.

 11 дек. 2011 г., 16:58
Ссылка на код JRSwizzle:github.com/rentzsch/jrswizzle & # X2026; Я полюбил это, метод swizzling ОЧЕНЬ эффективен, когда вы хотите настроить стороннюю библиотеку так, как вам нравится!
 12 июл. 2011 г., 16:48
Исходя из моего опыта, переходя к погоне, вы хотите использовать JRSwizzle, как упомянуто в приведенной выше ссылке. Это было пуленепробиваемым для меня.
 01 июн. 2011 г., 13:10
Это не обязательно «хакерский»; путь. Время выполнения Objective C существует по причине. Это то, что делает Objective-C превосходящим другие скомпилированные языки.

comp.lang.objective-C FAQ список: & quot;What if multiple categories implement the same method? Тогда ткань Вселенной, какой мы ее знаем, перестает существовать. На самом деле это не совсем так, но, безусловно, будут возникать некоторые проблемы. Когда категория реализует метод, который уже появился в классе (либо через другую категорию, либо через класс primary @implementation), определение этой категории перезаписывает определение, которое ранее присутствовало. Исходное определение больше не может быть достигнуто кодом Objective-C. Обратите внимание, что если две категории перезаписывают один и тот же метод, то какой из них был загружен последним, «выигрывает», что невозможно предсказать до запуска кода.

developer.apple.com: & quot; Когда категория переопределяет унаследованный метод, метод в категории может, как обычно, вызывать унаследованную реализацию через сообщение super. Однако если категория переопределяет метод, который уже существовал в классе категории, нет способа вызвать исходную реализацию & quot;

 09 мая 2013 г., 23:48
Я, вероятно, не должен говорить, но на всякий случай для будущих читателей: категория на самом деле совсем не похожа на подкласс.super не будет преобразован в «исходный объект».
 02 февр. 2012 г., 10:14
я думаю чтоsuper должен разрешить исходный объект. В конце концов, категория очень похожа на подкласс (например, вы можете переопределить методы).
 19 мар. 2013 г., 15:05
Правильно ли переопределить в методе Category, объявленном и реализованном в категории суперкласса?
 Kendall Helmstetter Gelner06 июл. 2009 г., 16:24
Я благодарю вас за комментарий, но я ищу, как это можно сделать (потому что я знаю, что это может быть, просто не легко), а не как это невозможно ...
 06 июл. 2009 г., 07:11
Да, это действительно не поддерживается языком.

Ваш ответ на вопрос