在尝试将我之前基于单例的全局控制器类转换为更多OOP友好依赖注入方法的过程中,该方法在需要时将所需方法从一个对象传递到另一个对象。我遇到了我的上一课在init期间使用全局对象的问题。
(id)init
{
self = [super init];
if (self)
{
[self setUpPhysicsWithWorld:FMPresenter.physics.world];
}
return self;
}
FMPresenter.physics
返回单个物理对象的位置。由于我的对象在没有Physics对象的情况下无法正确实例化,因此对init
的调用无效。我已经看到这个被使用:
(id) init
{
NSAssert(NO, @"init not allowed");
[self release];
return nil;
}
(id) initWithPhysics:(FMPhysics*)physics
{
self = [super init];
if (self) {
[self setUpPhysicsWithWorld:physics.world];
}
return self;
}
这是在Objective-C中强制构造函数参数的首选方法吗?
答案 0 :(得分:5)
是的,你的解决方案是正确的,首选方法是创建另一个以init开头的方法,并在调用super之后传递所需的初始化参数并返回self。
答案 1 :(得分:2)
这样做的现代方法是在.m中使用NS_DESIGNATED_INITIALIZER
:
@interface FMPresenter
- (instancetype)initWithPhysics:(FMPhysics*)physics NS_DESIGNATED_INITIALIZER;
@end
另请注意使用instancetype,现在优先于id。
答案 2 :(得分:1)
如果它们可能是默认的FMPhysics对象(不熟悉它),那么另一个选择是init用默认的物理世界调用initWithPhysics。
例如,这是一个带有db包装器的init重载,其中默认的init创建一个内存db,这是一个很好的默认值。
- (id)init
{
sqlite3 *db;
sqlite3_open(":memory:", &db);
return [self initWithDatabase:db];
}
- (id)initWithDatabase:(sqlite3*)database
{
self = [super init];
if (self)
{
_sqlite3 = database;
}
return self;
}