Добавление пользовательского initWith?
Если я создаю пользовательский 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);
}
Гэри
Ответы
Ответ 1
Вы можете создать один назначенный инициализатор, который принимает все параметры, которые вы хотите сделать доступными при инициализации.
Затем вы вызываете из своего другого -(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:
, и вы вызываете его из других инициализаторов.
Если вы хотите расширить этот класс, вы вызываете назначенный инициализатор из подкласса.
Ответ 2
Я бы предложил создать один главный инициализатор, который обрабатывает большую часть работы. Затем вы можете создать любое количество других инициализаторов, которые все называют этим основным. Преимущество этого заключается в том, что если вы хотите изменить процесс инициализации, вам нужно будет изменить только одно место (в общем). Это может выглядеть так:
-(id) initWithX:(float)x {
if (self = [super init]) {
/* do most of initialization */
self.xVal = x;
}
return(self);
}
-(id) init {
return [self initWithX:0.0f];
}
В этом примере initWiспасибо: наш главный инициализатор. Другой инициализатор (init) просто вызывает initWiспасибо: со значением по умолчанию (в этом случае 0).
Ответ 3
Да, именно так я это делаю. Одно небольшое изменение вычеркивает строку кода:
if (self = [super init]) {
В отличие от:
self = [super init];
if(self) {
Ответ 4
Для современный 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:@""];
}
Ответ 5
Иногда вы хотите повторно использовать некоторый код инициализации и немного модифицировать поведение для определенных инициализаторов. В этом случае я делаю следующее:
- (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;
}