У меня есть одноэлемент facade, который я бы хотел переслать вызовы методов класса в некоторый «статический» класс.forwardInvocation для другого класса, а не для экземпляра
На первый взгляд, forwardInvocation:
оказалось возможное решение, однако, NSInvocation
«s invokeWithTarget:
и setTarget:
только принять id
, т.е.. е. указатель на экземпляр, а не сам класс. Я попытался передать [MyTargetClass class]
в качестве цели, но до сих пор я получаю сообщение об ошибке «Неизвестный метод класса [...]», когда я вызываю [Facade someForwardedMethod]
. Когда я звоню [[Facade sharedInstance] someForwardedMethod]
, я получаю «Нет видимого @interface [...] объявляет ошибку селектора [...]».
Конечно, я знаю, что мне также нужно переопределить respondsToSelector:
и methodSignatureForSelector:
, так что мой код выглядит следующим образом:
- (BOOL)respondsToSelector:(SEL)aSelector {
if ([super respondsToSelector:aSelector]) {
return YES;
} else {
return [MyTargetClass respondsToSelector:aSelector];
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
NSMethodSignature* signature = [super methodSignatureForSelector:selector];
if (!signature) {
signature = [MyTargetClass methodSignatureForSelector:selector];
}
return signature;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
SEL aSelector = [anInvocation selector];
if ([MyTargetClass respondsToSelector: aSelector]) {
[anInvocation invokeWithTarget:[MyTargetClass class]];
} else {
[super forwardInvocation:anInvocation];
}
}
Есть ли способ, чтобы сделать эту работу, или я должен выбрать другой подход ?
EDIT: Я попробовал оба пути, что Роб Napier упоминает в своем ответе, вот мои выводы:
Я могу вызвать метод класса в моей целевой класс через экземпляр фасада с
[(id)[Facade sharedInstance] doSomethingClassyInTargetClass];
Это немного уродливее, чем я надеялся, но он работает. Однако я не могу вызвать метод класса в своем целевом классе, когда я обращаюсь к классу фасадов. Чтобы утихомирить компилятор я могу написать
[(Class)[Facade class] doSomethingClassyInTargetClass];
, но затем он бросает «NSInvalidArgumentException» «[Фасад doSomethingClassyInTargetClass]: непризнанные селектор направлен класс [...]» во время выполнения. По-видимому, классные методы класса фасада решаются без уважения для , но ведь у него есть -
спереди ...
Правильно ли я понимаю, что вы пытаетесь перенаправить вызов экземпляра в класс? Есть ли какая-то причина, по которой вы не просто делаете свой Facade также синглом, чтобы вы могли перенаправлять экземпляры экземпляров на вызовы экземпляра и класса в класс? –
На самом деле это было бы идеальным. Однако пересылка вызовов метода класса в этот другой класс была бы достаточно хорошей, если это возможно. Разве это не должно работать с тем же кодом? Я попробовал, и он тоже не работает. Я соответствующим образом изменил вопрос ... Я бы хотел избежать создания экземпляра другого класса, он огромный и не содержит ничего, что могло бы выиграть от него. – Stefan
Объект класса ** является ** экземпляром; это пример его метакласса. Вам может потребоваться использовать бросок, чтобы убедить компилятор в этом. Кроме того, вы пробовали новый механизм быстрой пересылки '-forwardingTargetForSelector:'? –