Добавление пользовательского initWith? - PullRequest
43 голосов
/ 11 ноября 2009

Если я создаю пользовательский initWith для объекта, я по существу включаю код, который я добавил бы, если я хочу переопределить init?

-(id) init {
    self = [super init];
    if (self) {
        NSLog(@"_init: %@", self);
    }
    return(self);
}

, например

-(id) initWithX:(int) inPosX andY:(int) inPosY {
    self = [super init];
    if(self) {
        NSLog(@"_init: %@", self);
        posX = inPosX;
        posY = inPosY;
    }
    return(self);
}

1007 * Гэри *

Ответы [ 5 ]

88 голосов
/ 11 ноября 2009

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

Затем вы вызываете с другого -(id)init вашего назначенного инициализатора с правильными параметрами.

Только указанный инициализатор будет инициализировать суперкласс [super init].

Пример:

- (id)init
{
    return [self initWithX:defaultX andY:defaultY];
}

- (id)initWithPosition:(NSPoint)position
{
    return [self initWithX:position.x andY:position.y];
}


- (id)initWithX:(int)inPosX andY:(int)inPosY
{
    self = [super init];
    if(self) {
        NSLog(@"_init: %@", self);
        posX = inPosX;
        posY = inPosY;
    }
    return self;
}

Назначенный инициализатор - -(id)initWithX:andY:, и вы вызываете его из других инициализаторов.

Если вы хотите расширить этот класс, вы вызываете назначенный инициализатор из подкласса.

9 голосов
/ 11 ноября 2009

Я бы предложил создать один основной инициализатор, который обрабатывает большую часть работы. Затем вы можете создать любое количество других инициализаторов, которые все вызывают этот основной. Преимущество этого в том, что если вы хотите изменить процесс инициализации, вам нужно будет изменить только одну точку. Это может выглядеть так:

-(id) initWithX:(float)x {
    if (self = [super init]) {
        /* do most of initialization */
        self.xVal = x;
    }
    return self;
}

-(id) init {
    return [self initWithX:0.0f];
}

В этом примере initWithX: наш главный инициализатор. Другой инициализатор (init) просто вызывает initWithX: со значением по умолчанию (в данном случае 0).

6 голосов
/ 11 ноября 2009

Да, именно так я и делаю. Одно небольшое изменение вырежет строку кода:

 if (self = [super init]) {

В отличие от:

 self = [super init];
 if(self) {
5 голосов
/ 20 августа 2015

Для Современный Objective-C ...

UDFile.h

#import <Foundation/Foundation.h>

@interface UDFile : NSObject

@property (nonatomic, strong) NSString *name;

- (instancetype)initWithName:(NSString *)name NS_DESIGNATED_INITIALIZER;

@end

UDFile.m

#import "UDFile.h"

@implementation UDFile

- (instancetype)initWithName:(NSString *)name {
    self = [super init];
    if (self) {
        _name = [name copy];
    }
    return self;
}

- (instancetype)init {
    return [self initWithPathname:@""];
}
2 голосов
/ 11 ноября 2009

Иногда вы хотите повторно использовать некоторый код инициализации и лишь слегка изменить поведение для конкретных инициализаторов. В этом случае я делаю следующее:


- (id) init
{
    self = [super init];
    if (!self) return nil;

    // These values are always initialised this way
    ivar1 = 10;
    ivar2 = @"HellO";
    ivar3 = [[NSMutableArray alloc] initWithCapacity:10];
    ivar4 = 22;

    return self;
}

- (id) initWithIvar4:(int) aValue
{
    // call -init on self, which will call -init on super for us, and set
    // up ivar1, ivar2, ivar3, and ivar4.
    self = [self init];
    if (!self) return nil;

    // Change ivar4 from the default 22 to whatever aValue is.
    ivar4 = aValue;

    return self;
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...