Как избежать предупреждения компиляции при создании подкласса класса с категорией? - PullRequest
2 голосов
/ 10 марта 2012

Скажем, у нас есть родительский класс

ParentViewController.h

@interface ParentViewController

....

@end

ParentViewController.m

@interface ParentViewController()

- (NSArray *)selectedItems;

@end

@implementation ParentViewController

.....

@end

А затем мы создадим его подкласс

ChildViewController.h

@interface ChildViewController : ParentViewController

....

@end

ChildClassViewController.m

@implementation ChildViewController

- (void)doSomething
{
    // XCode Warning Flag on this line
    NSUInteger count = [self selectedItems];

    .....
}

XCode установит флаг предупреждения в строке с комментариями и сообщит, что «метод экземпляра -selectedItems» не найден (тип возвращаемого значения по умолчанию равен «id ').

Да, я знаю, что в ObjC нет такого понятия, как закрытые методы, но использование пустой категории дает такую ​​возможность. Но как-то она не наследуется подклассами.

Я обычно исправляю это, перемещая метод из ParentViewController.m в ParentViewController.h. Это кажется странным, я теряю способность делать метод частным только потому, что мне нужно его подкласс.

Теперьмой вопрос:

  1. Почему родительский подкласс не может найти те методы, которые объявлены в его категории в файле .m?

  2. есть способ удалитьФлаг предупреждения, но не теряющий возможности сохранять метод закрытым.

Надеюсь, кто-то с большим опытом сможет помочь объяснить эту досадную проблему.

Ответы [ 2 ]

3 голосов
/ 10 марта 2012

Во-первых, обратите внимание, что ваша «пустая категория» - это вовсе не категория, а расширение класса.Расширения классов очень похожи на категории, но они являются новыми в Objective C 2.0, и они немного отличаются по своему использованию.Прежде всего, компилятор предупредит вас, если вы не реализуете метод в расширении класса, но не будет с категорией.В любом случае, к вопросу ...

Конфиденциальность в Objective-C - это все о видимости.Если компилятор не может видеть объявление используемого метода, вы получите предупреждение.Обратите внимание, что если вы реализуете свой подкласс в том же файле, что и расширение класса, компилятор не предупредит вас, потому что он может видеть объявление.

Поэтому, если вы хотите использовать "частные" методы вподклассы, вам просто нужен какой-то способ показать компилятору, что эти методы существуют.Мой любимый шаблон - объявить закрытые методы в категории в отдельном файле (например, MyClass_private.h).Затем вы только импортируете этот интерфейс в файлы реализации базового класса и любые производные классы, которые должны его видеть.

2 голосов
/ 10 марта 2012

У меня есть решение, но в целом я бы советовал против него.если вы скомпилируете файл с -w (подавить все предупреждения), предупреждение исчезнет.Я не знаю, существует ли специальный флаг предупреждения для этого сообщения, если он был, вы могли бы использовать #pragma GCC diagnostic ignored "-Winstance-method-not-found", но я не могу его найти, извините.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...