Доступ к методам forwardInvocation с помощью ARC? - PullRequest
2 голосов
/ 22 октября 2011

Я пишу клон OpenStruct в Objective-C, используя forwardInvocation: . Однако компилятор не знает о пересылке во время компиляции. Компиляция с ARC дает мне массу предупреждений.

Код с открытым исходным кодом и доступен на Github , но в настоящее время компилируется с -fno-objc-arc. Если бы кто-нибудь мог взглянуть на то, как я могу сделать этот ARC-совместимый, я был бы очень признателен.

1 Ответ

3 голосов
/ 04 ноября 2011

Я попробовал этот код:

OpenStruct *myStruct = [[OpenStruct alloc] initWithDictionary:myDictionary];
NSLog(@"%@ says %@", @"Cow",  [myStruct cowSound]);

Я получаю предупреждения или ошибки с и без ARC, с LLVM 3.0 или LLVM GCC 4.2.Я думаю, что вы неправильно поняли, что forwardInvocation: все еще требует, чтобы метод был объявлен на каком-то уровне, если только в категории (@interface) класса, в который вы отправляете сообщение.

Например, когдавы делаете:

[someObject doSomething];

Тогда это всегда будет генерировать как минимум предупреждение («someObject может не отвечать на doSomething»), если doSomething нигде не объявлен, независимо от того, реализует ли класс someObject forwardInvocation или нет.Как вы заметили, компилятор действительно не знает о пересылке, и он также не может полагаться на то, что ваша реализация forwardInvocation гарантирует доставку сообщений.В LLVM 3.0 с ARC или без него это можно было изменить, чтобы вместо этого генерировать ошибку, поскольку целью развития ARC было допустить ошибку в сторону большего количества ошибок компилятора, а не проблем во время выполнения.

Теперь вы все еще можете отправлять сообщенияобъект, который не реализует метод.Например, с помощью метода времени выполнения Objective C objc_msgSend или через NSInvocation .Но это аннулирует простой в использовании интерфейс, который вы планировали создать.

Кстати, ваш пример использования OpenStruct не совсем оправдывает, почему проще получить доступ к динамической структуре через обмен сообщениями по сравнению с простыми средствами доступа, такими как [struct getValueForKey: @ "moo"];… Если вы обдумаете это, то [struct moo] дает пользователям мало или вообще не дает преимуществ по сравнению с первым подходом.Метод "moo" в любом случае является динамическим (строка или перенаправленное сообщение), и опечатка не будет обнаружена во время выполнения.

...