Инициализация пользовательских объектов в Objective-C - PullRequest
7 голосов
/ 28 июня 2011

Я создал собственный объект в Objective-C.Теперь я хочу создать собственный инициализатор.У объекта есть два свойства: имя и оценка.Итак, мой инициализатор выглядит следующим образом:

- (id)initWithName:(NSString *)playerName {

    if ((self = [super init])) {
        self.name = [playerName retain];
        self.score = [NSNumber numberWithInt:0];
    }

    return self;
}

Правильно ли я здесь использую retain?Или я могу просто сделать что-то вроде self.name = playerName;?

Более того, предположим, что мне нужен другой инициализатор, но оставьте initWithName:playerName назначенным инициализатором.Как мне заставить второй инициализатор вызывать первый?

И последний вопрос: я знаю, что мне тоже нужно переопределить метод - (id)init.Но что мне там делать?Просто назначьте свойства теста, если класс был инициализирован только с init?

Спасибо!

Ответы [ 3 ]

7 голосов
/ 28 июня 2011

Использую ли я здесь правильно удерживать?

Нет, вы не являетесь.Вам следует либо использовать

self.name = playerName;

, как вы предложили, либо (согласно рекомендации Apple)

name = [playerName copy];

Не рекомендуется использовать средства доступа в -init, поскольку подклассы могут их переопределять.

Также обратите внимание, что поскольку NSString реализует NSCopying, вы должны использовать свойство copy, а не свойство retain.

Кроме того, предположим, что я хочу другой инициализатор, но сохраняюinitWithName: playerName назначенный инициализатор.Как мне заставить второй инициализатор вызывать первый?

Используя -init в качестве примера (потому что вы должны переопределить инициализатор, назначенный суперклассом, если ваш инициализатор не являетсятоже самое)

-(id) init
{
    return [self initWithName: @"Some default value"];
}
2 голосов
/ 28 июня 2011

вы можете оставить self.name = playerName;, если объявите name в качестве сохраняемого свойства в классе .h , а также в файле .m .

Для инициализации вы можете поместить белую строку кода в отдельный метод.

-(void) initializeWithName:(NSString*) aName withNumber:(int) aNumber
{
  self.name = aName;
  self.score = [NSNumber numberWithInt:aNumber];
}

Позволяет использовать три метода инициализации.

- (id)initWithName:(NSString *)playerName {

    if ((self = [super init])) {
      [self initializeWithName:playerName withNumber:0]
    }

    return self;
}


- (id)initWithNumber:(int*) aNumber {

    if ((self = [super init])) {
       [self initializeWithName:nil withNumber:aNumber]
    }

    return self;
}


- (id)init{

    if ((self = [super init])) {
        [self initializeWithName:nil withNumber:0]
    }

    return self;
}
0 голосов
/ 30 августа 2013

Что стоит остальным новичкам:

В обычных языках можно просто определить аргументы при создании экземпляра класса:

public final class MakeBed {

    private var foo:Object;
    public var bar:Array;

    public function MakeBed(_foo:Object, _bar:Array) {
        // Do stuff
        foo = _foo;
        bar = _bar;
    }

}

Затем, когда мы хотим создать экземпляр классаэто так просто, как:

var myBeadMaker:MakeBed = new MakeBed({}, []);

В objc все обратно.

Вы можете создать свой собственный инициализатор, похожий на:

// These @properties go into the header.h file
@property (nonatomic, retain) NSString *foo;
@property (nonatomic, retain) NSString *bar;

// This is in your implimentation.m file
- (id) initWithInfo:(NSObject*)foo withBar:(NSArray *)bar {
    _foo = foo;
    _bar = bar;
}

Objc автоматически «синтезирует» геттеры и сеттеры и автоматически создает новую переменную «вслепую», используя то же самое _name _but _ с _anderscore впереди, когда вы делаете вещь @property - это волшебство - граничит с «почти тоже»полезная сторона вещей.

Удобно для не новичков, но невероятно запутанно для новичков - просто верьте, что геттер и сеттер созданы и что _new _var __ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Новый _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Новый _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _...

Когда вы хотите создать экземпляр класса с помощью своего пользовательского инициализатора, вы делаете это:

MakeBed myBedMaker = [[MakeBed alloc] initWithInfo:*foo withBar:*bar];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...