所以我正在研究Objective-C的Apple文档(在进入iphone开发之前)。其中一个练习指出我应该创建一个指定的初始化器(有3个参数)和合适的工厂方法。
现在我根据我的理解做了这个,但我无法实现工厂方法,因为我不知道我是否应该在其实现中使用alloc和init?
练习:
声明并实现一个用于创建的新指定初始化程序 XYZPerson使用指定的名字,姓氏和出生日期, 以及合适的工厂方法。别忘了覆盖 init调用指定的初始化程序。
代码:
//.h
-(id)initWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *) dob;
//.m
-(id)initWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *)dob{
self = [super init];
return [self initWithNameAndDob:fName last:lName birth:dob];
}
实施中缺少什么?
谢谢,
答案 0 :(得分:16)
声明并实现一个新的指定初始值设定项,用于使用指定的名字,姓氏和出生日期创建XYZPerson ...
你在声明中是正确的但是你的实现是递归的,因为它正在调用它自己。做点什么
//.h
-(id)initWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *) dob;
//.m
-(id)initWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *)dob{
if(self = [super init]) {
// use the parameters to do something, eg.
_fName = fName; // assuming you have an ivar called _fName
_lName = lName; // assuming you have an ivar called _lName
_dob = dob; // assuming you have an ivar called _dob
}
return self;
}
然后
......以及合适的班级工厂方法。
工厂方法是一种生成对象实例的类方法。最常见的实现是让它分配和初始化对象的新实例并将其返回。
//.h
+(instancetype)personWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *) dob {
//.m
+(instancetype)personWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *) dob {
return [[XYZPerson alloc] initWithNameAndDob:fName last:lName birth:dob];
}
最后
不要忘记覆盖init以调用指定的初始化程序。
由于您设计的初始化程序为initWithNameAndDob:last:birth:
,因此您的init
实现必须调用它。设计的初始值设定项的参数必须是合理的默认值,在这种情况下nil
很好。
-(id)init {
return [self initWithNameAndDob:nil last:nil birth:nil];
}
作为最后的评论,我想指出初始化程序的命名约定不是那么好。更合适和可读的是
-(id)initWithFirstName:(NSString *)fName lastName:(NSString *)lName dateOfBirth:(NSDate *) dob;
答案 1 :(得分:5)
Gabriele Petronella的优秀解释,但有问题。
+(instancetype)personWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *) dob {
return [[XYZPerson alloc] initWithNameAndDob:fName last:lName birth:dob];
}
It should be replaced with
+(instancetype)personWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *) dob {
return [[self alloc] initWithNameAndDob:fName last:lName birth:dob];
}
<强>规则:强> 不要按名称引用自己的类,因为你不知道具体的类是什么。您将无意中切断通过子类化扩展和覆盖类的能力。代替, 在类的工厂方法中分配实例:[self alloc] 的参考:强> http://qualitycoding.org/factory-method/