[英]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風格的結構,因為它們只是原語。
確實,這只是推遲了問題,將初始化從一個類移到了配置類,但是:
您可以將配置拆分為不同類型(守門員,技術和心理)。 再一次,它只是將問題分開,但這有助於保持事物的集中。
另一種可能性是覆蓋屬性的默認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.