Параметры инициализации класса Objective-C

В настоящее время я снова начинаю работать с Objective-C. Проблема, с которой я сталкиваюсь, заключается в передаче переменных собственному методу инициализации экземпляра класса.

У меня есть эта пользовательская инициализация в моем @interface:

-(id)init
{
    if(self = [super init]) {
        level = 1;
        NSLog(@"Debug response");
    }

    return ([NSObject init]); // return self;
}

И вот основной класс моего приложения:

#import "AppDelegate.h"
#import "PlayableCharacter.h"

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
    NSArray *params = [NSArray arrayWithObjects: @"Elf", nil];

    PlayableCharacter *allendar = [[PlayableCharacter alloc] init:params];
}

@end

Может кто-нибудь объяснить, что я делаю неправильно? Я думал, что объект NSArray будет соответствовать профилю C-объекта "id". Является ли указание параметров инициализации незаконным или это должно быть сделано по-другому?

Ошибка гласит: «Нет видимого @interface для« PlayableCharacter »объявляет селектор« init: »»


person Community    schedule 17.12.2012    source источник


Ответы (2)


Ваш метод -init не имеет параметров. Это эквивалентно следующему C:

void *init();

void *foo = init(bar); // error

Если вы хотите назвать его -init:, вы должны объявить его как

- (id)init:(NSArray *)params;

Однако это очень нестандартное наименование. Если вам действительно нужен метод инициализации, который принимает один NSArray, то, возможно, назовите его как-то так

- (id)initWithArray:(NSArray *)array;

Но из вашего примера кода я предполагаю, что вам действительно не нужен массив, вам нужен только один параметр. Поэтому вместо этого вы должны использовать

- (id)initWithCharacterClass:(NSString *)className;

а затем назовите это как

PlayableCharacter *allendar = [[PlayableCharacter alloc] initWithCharacterClass:@"Elf"];
person Lily Ballard    schedule 17.12.2012
comment
Спасибо, это сработало! Нужно привыкнуть к тому, как Objective-C все форматирует :). В основном я использую NSArray, думая о стиле String args[], который использует C. Расовый эльф — не единственное, что я хочу разобрать, так как я хочу иметь возможность установить PlayableCharacter в предыдущее состояние из базы данных. - person ; 18.12.2012
comment
@Allendar: Если ваши данные лучше всего не выражены в виде массива, вы обычно хотите использовать несколько отдельных параметров. Например, вы бы не определили все свои функции C как void *foo(void *args, size_t count), не так ли? Вы бы использовали это только тогда, когда вам действительно нужно принять переменное количество значений. Точно так же в obj-c вы можете взять NSArray*, если вам нужно принять переменное количество значений, но если вам нужно взять определенный небольшой набор значений, вы должны использовать отдельные параметры. - person Lily Ballard; 18.12.2012
comment
В этом случае для удобства чтения я изменил его на NSMutableDictionary. Тогда, например, я могу на самом деле проверить, передал ли кто-то значение расы, вместо того, чтобы жестко проверять ключи списка. - person ; 18.12.2012
comment
По крайней мере, теперь, надеюсь, сделал это чисто :) ››› PlayableCharacter *allendar = [[PlayableCharacter alloc] initWithMutableDictionary:params]; - person ; 18.12.2012
comment
@Allendar: Поскольку у вас, кажется, есть параметры в произвольной форме, использование словаря здесь, вероятно, нормально. Но параметр не должен быть изменяемым. Вы должны назвать это либо -initWithDictionary: (взяв NSDictionary*), либо -initWithParams:. - person Lily Ballard; 18.12.2012
comment
Хорошая идея: П. Я исправлю их :) - person ; 18.12.2012
comment
Короткий вопрос не по теме; Сейчас я делаю эту структуру суперкласса: Entitiy -> PlayableClass, а затем использую Race как объект внутри PlayableClass. Что больше подходит: Entity -> Race -> PlayableClass или оставить так? Мне нужна информация о расе, чтобы определить базовую статистику и некоторые другие аспекты PlayableClass :) - person ; 18.12.2012
comment
@Allendar: Я сомневаюсь, что Race имеет смысл быть суперклассом PlayableClass. Вероятно, вам следует просто сохранить его как свойство класса. - person Lily Ballard; 18.12.2012

Если вы хотите начать с параметрами, создайте метод init следующим образом:

-(id)initWithParams:(NSArray *)params
{
    if(self = [super init]) {
        level = 1;
        NSLog(@"Debug response");

        // Do something with params
    }

    return self;
}

Кроме того, вы должны просто вернуть self, а не [NSObject init]

person colincameron    schedule 17.12.2012
comment
Отмечено, что это было процитировано для дальнейшего исследования, так как я не был уверен, какой из них использовать. - person ; 18.12.2012