繁体   English   中英

Objective-C设置属性的默认值

[英]Objective-C set default value for a property

我正在制作一个应用程序,我有一个具有相当多属性的类,我想知道是否可以给它们一个默认值。 因为如果我创建一个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;}
}

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

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

这样称呼它:

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

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

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

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

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

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

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

当然,你需要编写两个可怕的方法( 这里有一个很好的干净的例子 ),但作为回报,你可以得到一种统一的方法,将你的属性存储为NSMutableDictionary对象。 这打开了普通ivars无法提供的几个有趣的替代方案:您可以推迟属性的初始化,直到需要它们为止,您可以为未设置的属性提供默认值,或者您可以通过在字典中填入值来初始化您的属性“批发”他们的钥匙。

是的,您可以覆盖getter,以便在启用属性之前设置默认值。

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

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

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

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

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

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

@implementation GoalKeepingAttributes
@end

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

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

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

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

您可以将配置拆分为不同类型(守门员,技术和心理)。 再一次,它只是将问题分开,但这有助于保持事物的集中。

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

- (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函数中完成它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM