我正在创建一个应用程序,我有一个具有相当多属性的类,我想知道是否可以给它们一个默认值。因为如果我创建一个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;}
}
答案 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风格的结构,因为它们只是原语。
这确实只是推迟了问题,将初始化从一个类移到了配置类,但是:
您可以将配置拆分为不同类型(守门员,技术和心理)。同样,它只是将问题分开,但这可以帮助保持事物的重点。
答案 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函数中执行它。