Objective-C构造函数中的必需参数

3
在尝试将之前基于单例模式的全局控制器类转换为更友好的OOP依赖注入方法时,我遇到了一个问题:我的先前类在其初始化期间使用了全局对象,而现在需要将所需的方法从一个对象传递到另一个对象中。
(id)init 
{
    self = [super init];
    if (self) 
    {
        [self setUpPhysicsWithWorld:FMPresenter.physics.world];
    }
    return self;
}

FMPresenter.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中强制使用构造函数参数的首选方法吗?
3个回答

5

是的,您的解决方案是正确的。首选方法是创建另一个方法以init开头,将所需的初始化参数传递给该方法,并在调用super后返回self。


谢谢,我不太确定,因为我记得Java不允许你调用基础构造函数,除非你指定了它或者根本没有指定任何构造函数。 - Aram Kocharyan

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;
}

我曾考虑过使用 [[FMPhysics] shared],但那正是我想要避免的:P - Aram Kocharyan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接