Я думаю, это потому, что делегат NSOutlineView
теперь набирается как id <NSOutlineViewDelegate>
, а не как простой id
, как это было в 10.5 SDK. Категория объявлена в NSObject
, но компилятор не видит объект делегата как наследующий от NSObject
, поэтому он не распознает, что он ответит на сообщение. Раньше, поскольку делегат был простым id
, он не жаловался бы ни на одно сообщение, отправленное ему, до тех пор, пока он мог где-то найти объявление.
Быстрое и грязное решение - просто добавить актерский состав, сделав код [(id)[self delegate] outlineView:self menuForTableColumn:[[self tableColumns] objectAtIndex:column] byItem:item];
Чтобы быть немного более формальным, вы можете объявить свой собственный официальный протокол делегата, который наследуется от NSOutlineViewDelegate
, который будет выглядеть как
@protocol DSOutlineViewDelegate <NSOutlineViewDelegate>
@optional
- (NSMenu *)outlineView:(NSOutlineView *)olv menuForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item;
@end
Затем в коде, который его вызывает, вы захотите вызывать метод для объекта типа id <DSOutlineViewDelegate>
. Вы можете сделать это, объявив новый метод, который выполняет кастинг, например:
- (id <DSOutlineViewDelegate>)ds_delegate
{
return (id <DSOutlineViewDelegate>)[self delegate];
}
Затем в действующем коде вы бы позвонили:
[[self ds_delegate] outlineView:self menuForTableColumn:[[self tableColumns] objectAtIndex:column] byItem:item];
и компилятор должен быть в порядке с этим. Поскольку метод объявлен в протоколе как необязательный, вы все равно хотите во время выполнения проверить, действительно ли делегат отвечает на селектор.