2015-03-04 2 views
2

У меня есть этот метод, который должен задать имя объекта, но объекты могут быть из 3-х классов A, B и C.Это правильный способ запуска универсального метода?

Если я просто сделать это

[object setName: @"new name"]; //at this point I am treating object as of type id 

Xcode будет жаловаться, что Есть несколько методы, названные «setName», затем я делаю это

if ([object isKindOfClass:[ClassA class]]) { 
    [(ClassA *)object setName:newName]; 
    } else 
    if ([object isKindOfClass:[ClassB class]]) { 
    [(ClassB *)object setName:newName]; 
    } else 
    [(ClassC *)object setName:newName]; 
    } 

Но это кажется мне хромым.

Я пытался обмануть Xcode, используя что-то вроде этого

[(typeof(object))object setName:newName]; 

Но Xcode не нравится это тоже, наверное, потому, что typeof(object) возвращается id, и мы вернулись на круги своя. Такая же ошибка.

Что лучше/изящным способом я должен это сделать?

+0

Какой тип 'object' объявлен? – mipadi

+0

-------------> id – SpaceDog

+0

Существуют ли несколько методов с именем 'setName'? Нам нужно понять, почему вы получаете эту первоначальную ошибку? –

ответ

5

Используйте протокол, класс A, B, C и все соответствует.

@protocol MyProtocol <NSObject> 
@required 
- (void)setName:(NSString *)name; 
@end 

А потом

id<MyProtocol> object = ... 
[object setName:newName]; 
+0

Я думаю, что все! БЛАГОДАРЯ!!!!!!!!!!!! Я отвечу на ваш ответ, как только я позволю. – SpaceDog

+0

Я собирался предложить протокол, но вы меня избили. Другой альтернативой было бы создать базовый класс для всех 3 классов, которые реализуют метод setName. –

1

Лучше всего было бы, имея AB и C осуществляет ту же , который будет определять способ setName.

NameProtocol.h

@protocol NameProtocol <NSObject> 

- (void)setName:(NSString *)name; 

@end 

хиджры

@interface A : NSObject <NameProtocol> 

B.h

@interface B : NSObject <NameProtocol> 

C.h

@interface C : NSObject <NameProtocol> 
0

Протоколы путь. Но вы также можете сделать:

if ([object respondsToSelector: @selector(setName:)]) 
{ 
    [object performSelector: @selector(setName:) withObject: name]; 
} 
1

Использовать кодовое слово.

[object setValue:newName forKey:@"name"]; 

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


Обновление

КВЦ не имеет проверки компиляции типа времени: увеличение вероятности дефектов. Ошибки выполнения приводят к исключениям: дефекты приводят к сбою приложения.Его синтаксис подразумевает, что object - это словарь: скрывает намерение кода. Это неясно: младшие разработчики обычно не понимают, как это работает, и могут вызвать проблемы с обслуживанием.

Это настоящее шоу ужасов, но оно может быть полезно в правильных обстоятельствах.

+0

Не могли бы вы описать ситуацию, когда это не было бы полезно, что может вызвать проблемы? Благодарю. – Unheilig

+0

@Unheilig добавил некоторые избиения KVC. –

+0

Спасибо, теперь мне стало интересно узнать о части _maintenance issues_. Могли бы вы, может быть, подробнее рассказать об этой части? :-) Благодаря. – Unheilig

Смежные вопросы