【问题标题】:Objective C Constructer without init没有 init 的 Objective C 构造函数
【发布时间】:2012-07-07 21:42:18
【问题描述】:

当我创建自定义类时,我希望能够在构建类的实例后跳过代码的 alloc init 部分。类似于它的完成方式:

NSString * ex = [NSString stringWithFormat...]; 

基本上我已经用自定义初始化方法设置了类来设置我的基本变量。然而,当我在前端并实际制作这些小动物时,我不得不说:

[[Monster alloc] initWithAttack:50 andDefense:45]; 

我更愿意说

[Monster monsterWithAttack:50 andDefense:45]; 

我知道去掉 alloc 部分是一件简单的愚蠢的事情,但它使代码更具可读性,所以我更喜欢这样做。我最初只是尝试从

更改我的方法
-(id)initWithAttack:(int) a andDefense:(int) d 

-(id)monsterWithAttack:(int) a andDefense:(int) d 

然后将我的 self = [super init] 更改为 self = [[super alloc] init]; 但这显然不起作用!有什么想法吗?

【问题讨论】:

  • monsterWithAttack 必须是类方法,所以将 - 替换为 +

标签: objective-c ios initialization


【解决方案1】:

你必须创建一个方法

+(id)monsterWithAttack:(int) a andDefense:(int) d 

您在其中创建、初始化和返回一个实例(不要忘记您的内存管理):

+(id)monsterWithAttack:(int) a andDefense:(int) d {
    // Drop the autorelease IF you're using ARC 
    return [[[Monster alloc] initWithAttack:a andDefense:d] autorelease];
}

【讨论】:

  • 啊,所以我保留了 init 方法,只是不在实现中使用它。完全有道理。 ARC 中不需要自动释放部分的快速问题,对吗?
  • 我不使用 ARC,但据我了解,是的。
  • 好的,谢谢。顺便说一句,它确实可以在没有 ARC 中的自动释放的情况下工作。引发错误。
【解决方案2】:

你想要的是一个方便的构造函数。它是一个类方法,它返回一个可用的类实例并同时为其分配内存。

-(id)initWithAttack:(int)a andDefense:(int)d;
+(id)monsterWithAttack:(int)a andDefense:(int)d;

+(id)monsterWithAttack:(int)a andDefense:(int)d {
        //-autorelease under MRC
        return [[[self class] alloc] initWithAttack:a andDefense:d];
 }
 -(id)initWithAttack:(int)a andDefense:(int)d {
        self = [super init];
        if (self){
             //custom initialization
        }
        return self;
    }

【讨论】:

  • 啊方便的构造函数...如果我知道名字我可能会找到它。谢谢
【解决方案3】:

你应该在怪物类的头部使用类工厂方法。

+(id)monsterWithAttack:(int) attackValue andDefense:(int) defenseValue 

在怪物类的实现中

+(id)monsterWithAttack:(int) attackValue andDefense:(int) defenseValue {
    return [[[[self class] alloc] initWithAttack:attackValue andDefense:defenseValue] autorelease];
}

[self class] 的使用保证了子类化期间的正确调度。如果您使用 ARC,则可以避免使用 autorelease 方法

【讨论】:

  • [[self class] alloc] 和刚才的[self alloc] 有什么区别?
  • 在类方法中 self 与类相关,如果您继承 Monster 类并继承该方法,您将始终创建 Monster 实例。为了确保您创建了正确的实例,您只需询问班级您是谁?
  • [self class] 在这里是不必要的;在类方法中,self 已经是类对象。 [self alloc] 完美运行。 @Cald
【解决方案4】:

这种类型的类方法使用autorelease

例如,你可能会说:

+ (id)
monsterWithAttack:(int)  a
defense:(int)            d
{
    return [[Monster alloc] initWithAttack:a defense:d]
            autorelease];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 2012-03-05
    • 2012-10-10
    • 2022-01-15
    • 2018-03-27
    • 1970-01-01
    • 2014-07-11
    相关资源
    最近更新 更多