Использование типа «id» в классе какао - PullRequest
0 голосов
/ 20 апреля 2010

Я хочу реализовать класс, который может использоваться двумя классами моего проекта.

Один из них - манипулирование объектами NewsRecord. Одним из них является манипулирование объектами 'GalleriesRecord'.

В другом классе я могу использовать один из двух объектов, поэтому я делаю что-то подобное:

// header class
id myNewsRecordOrGalleriesRecord;

// class.m
// NewsRecord and GalleriesRecord have both the title property
NSLog(myNewsRecordOrGalleriesRecord.title);

и я получаю:

error : request for member 'title' in something not a structure or union

есть идеи: D?

Спасибо.

Готье

Как мне это сделать?

Ответы [ 3 ]

6 голосов
/ 20 апреля 2010

Нельзя использовать точечный синтаксис для типов id, поскольку компилятор не может знать, что означает x.foo (объявленное свойство может сделать получатель другим именем, например, view.enabled -> [view isEnabled]).

Следовательно, вам нужно использовать

[myNewsRecordOrGalleriesRecord title]

или

((NewsRecord*)myNewsRecordOrGalleriesRecord).title

Если title и другие вещи являются общими свойствами этих двух классов, вы можете объявить протокол.

@protocol Record
@property(retain,nonatomic) NSString* title;
...
@end

@interface NewsRecord : NSObject<Record> {  ... }
...
@end

@interface GalleriesRecord : NSObject<Record> {  ... }
...
@end

...

id<Record> myNewsRecordOrGalleriesRecord;
...

myNewsRecordOrGalleriesRecord.title;  // fine, compiler knows the title property exists.

Кстати, не используйте NSLog(xxx);, который склонен к атака форматной строки , и вы не можете быть уверены, что xxx действительно является строкой NSString. Вместо этого используйте NSLog(@"%@", xxx);.

0 голосов
/ 20 апреля 2010

Компилятор недоволен, поскольку id на самом деле является экземпляром NSObject, у которого нет свойства title.

Если ваш объект соответствует KVC, вы можете использовать метод valueForKey:

NSLog( [myNewsRecordOrGalleriesRecord valueForKey:@"title"] );
0 голосов
/ 20 апреля 2010
  1. Попробуйте получить доступ к названию вашей записи, например [myNewsRecordOrGalleriesRecord title];
  2. Если вы собираетесь делать много вещей такого типа (доступ к общим методам в двух классах), вы, вероятно, выиграете значительно от создания абстрактного суперкласса, от которого NewsRecord и GalleriesRecord могут наследовать ( если они будут делиться большим количеством кода) или создать протокол , они оба могут придерживаться (если они будут делиться именами методов, но не кодом.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...