Objective-C设置属性的默认值

时间:2012-03-22 20:50:57

标签: objective-c properties default-value

我正在创建一个应用程序,我有一个具有相当多属性的类,我想知道是否可以给它们一个默认值。因为如果我创建一个init方法,输入所有东西需要做很多工作,那么拼写错误的可能性很大,而且编码也不错......

这就是我班级的样子:

// Goalkeeping attributes
@property (nonatomic) int aerialAbility;
@property (nonatomic) int commandOfArea;
@property (nonatomic) int communication;
@property (nonatomic) int eccentricity;
@property (nonatomic) int handling;
@property (nonatomic) int kicking;
@property (nonatomic) int oneOnOnes;
@property (nonatomic) int reflexes;
@property (nonatomic) int rushingOut;
@property (nonatomic) int tendencyToPunch;
@property (nonatomic) int throwing;

// Technical attributes
@property (nonatomic) int corners;
@property (nonatomic) int crossing;
@property (nonatomic) int dribbling;
@property (nonatomic) int finishing;
@property (nonatomic) int firstTouch;
@property (nonatomic) int freeKickTaking;
@property (nonatomic) int heading;
@property (nonatomic) int longShots;
@property (nonatomic) int longThrows;
@property (nonatomic) int marking;
@property (nonatomic) int passing;
@property (nonatomic) int penaltyTaking;
@property (nonatomic) int tackling;
@property (nonatomic) int technique;

// Mental attributes
@property (nonatomic) int aggression;
@property (nonatomic) int anticipation;
@property (nonatomic) int bravery;
@property (nonatomic) int composure;
@property (nonatomic) int concentration;
@property (nonatomic) int creativity;
@property (nonatomic) int decisions;
@property (nonatomic) int determination;
@property (nonatomic) int flair;
@property (nonatomic) int influence;
@property (nonatomic) int offTheBall;
@property (nonatomic) int positioning;
@property (nonatomic) int teamwork;
@property (nonatomic) int workRate;

// Physical attributes
@property (nonatomic) int acceleration;
@property (nonatomic) int agility;
@property (nonatomic) int balance;
@property (nonatomic) int jumping;
@property (nonatomic) int naturalFitness;
@property (nonatomic) int pace;
@property (nonatomic) int stamina;
@property (nonatomic) int strength;

那么,在实现中,我正在做类似的事情:

@synthesize aerialAbility = _aerialAbility;

我想知道是否可以这样做:

@interface MyClass : NSObject
@property (nonatomic) int someProperty;

@end

@implementation MyClass
@synthesize someProperty = _someProperty = 10;
@end

我知道这不起作用,这根本不对,但我想知道是否有办法做这样的事情。

就像你在Java中一样:

class MyClass
{
private int someProperty = 10;
public int getSomeProperty(){return someProperty;}
public void setSomeProperty(int someProperty){this.someProperty = someProperty;}
}

7 个答案:

答案 0 :(得分:47)

我之前从未见过这种行为,但我很确定这是分配对象时的init步骤,即设置变量和初始化对象。

-(id)init {
     if (self = [super init])  {
       self.someProperty = 10;
     }
     return self;
}

这就是这样说的:

MyClass* test = [[MyClass alloc] init];

请注意,您可以拥有多个init函数,这些函数允许您拥有一组不同的默认值。

@synthesize所做的是告诉预编译器它应该为set / get生成代码,而不是设置属性的值。 '='只是告诉前者,即使变量的名称和属性不相同,它们也应该连接起来。

另外,作为一个个人意见(完全没有涉及到这个问题),这个对象似乎很大,你可能会以某种方式将其拆分或像其他人建议的那样。也许这个类可以继承其他一些类来为它提供它需要的不同属性?正如我所说,这只是一个建议,因为我不知道你的其他代码是什么样的:)

答案 1 :(得分:9)

对于像这样的大量属性,我倾向于将数据存储为字典而不是单个属性,我会将默认值存储在属性列表中。可以使用属性列表轻松初始化NSDictionary个对象。

如果使用字典不符合您的口味,我仍然会将默认值存储在属性列表中,并且在指定的初始化程序中,我会遍历属性列表中的项目并将它们应用于{{1使用键值编码。您应该注意,这仅适用于可信数据,而不适用于用户提供的数据,否则可能会被劫持以设置您不期望的其他属性。

答案 2 :(得分:4)

在Objective C中没有内置的类似Java的方法来初始化合成属性 ivars。但是,由于您的属性看起来几乎相同,您可能需要考虑将它们{{1}而不是合成它们。

当然,您需要为您编写两个可怕的方法(here is a nice and clean example),但作为回报,您可以获得将属性存储为@dynamic内的对象的统一方式。这打开了普通ivars无法提供的几个有趣的替代方案:您可以推迟初始化您的属性,直到需要它们为止,您可以为未设置的属性提供默认值,或者您可以通过以下方式初始化您的属性“批发”在字典中填入键的值。

答案 3 :(得分:1)

是的,你可以覆盖getter,以防在属性被设置之前设置默认值。

例如,在.h文件中定义属性:

@interface MySegmentedControl : UISegmentedControl
@property (assign, nonatomic) CGFloat systemFontOfSize;
@end

并覆盖getter并在.m文件中的实现下设置默认值:

@implementation MySegmentedControl    
-(CGFloat) systemFontOfSize
{
    return _systemFontOfSize ? _systemFontOfSize : 17.0f;
}    
@end

答案 4 :(得分:0)

上面的字典建议很好。我有时使用专用的配置对象:

@interface GoalKeepingAttributes
@property (nonatomic) int agression
@property (nonatomic) int ... etc
@end

@implementation GoalKeepingAttributes
@end

等。如果需要,这个类可以有一个init方法来设置一堆值和默认值。

你也可以使用c风格的结构,因为它们只是原语。

这确实只是推迟了问题,将初始化从一个类移到了配置类,但是:

  • 你必须用字典来做这件事
  • 您可以评论配置设置
  • 最大的胜利:配置类是强类型的,它在编译时捕获错误,允许xcode代码完成

您可以将配置拆分为不同类型(守门员,技术和心理)。同样,它只是将问题分开,但这可以帮助保持事物的重点。

答案 5 :(得分:0)

另一种可能性是覆盖属性的默认getter。在getter中,您可以查看值是否已初始化,如果没有,则返回默认值。 (这适用于某些属性类型但不适用于其他属性类型,显然 - 您需要将默认值设置为表示未设置任何值的值。)

答案 6 :(得分:0)

- (id)init
{
    self = [super init];
    if (self != nil) {
        [self commonInit];
    }

    return self;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self != nil) {
        [self commonInit];
    }

    return self;
}

-(instancetype)initWithCoder:(NSCoder *)aDecoder { //nib init
    self = [super initWithCoder:aDecoder];
    if (self != nil) {
        [self commonInit];
    }
    return self;
}

如果对象是视图,您可以设置默认值并在commonInit函数中执行默认逻辑。如果它不是视图,你可以在我看来在init函数中执行它。