2012-03-22 234 views
27

我正在創建一個應用程序,並且我有一個具有相當多屬性的類,我想知道是否可以給它們一個默認值。因爲如果我做一個init方法,這是一個很大的工作類型應有盡有,有錯字的一大機會,它只是沒有很好的編碼...Objective-C設置屬性的默認值

這是我的課怎麼樣子:

// 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;} 
} 

回答

39

我以前從未見過這種行爲,但我敢肯定,這是初始化步驟是,當分配的對象,即設置變量和初始化目的。

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

而這樣稱呼它:

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

注意,您可以有一個以上的初始化函數,它允許你有幾個不同的設置默認值。

@synthesize做的是告訴預編譯器它應該爲set/get生成代碼,而不是設置屬性的值。 '='只是告訴預編譯器,即使變量的名稱和屬性不一樣,它們也應該連接在一起。

另外,作爲個人意見(與所有問題無關),這個對象看起來很大,你也許能夠以某種方式分割它,或者像其他人一樣建議。也許這個類可以繼承其他幾個類來給它提供它所需要的不同屬性?正如我所說的那樣一個建議,因爲我不知道你的其他代碼是什麼樣子:)

+1

這是正確的 - 初始化是一個很好的地方爲伊娃或財產設置初始價值。更具體地說,指定的初始化程序(該類的任何其他初始化程序將調用的初始化程序)是您應該設置這些值的那個初始化程序。 – Caleb 2012-03-22 21:02:39

+0

感謝您的建議,但是,我試圖避免在初始化程序中放置30個以上的作業,並且課程無法真正分離(當然,它總是可以的,但這隻會讓我的課堂設計變得更糟)。 – 2012-03-22 21:24:08

+0

爲什麼要避免我不明白。 init是爲此目的而創建的,或者你可以使用一個你必須在init中設置的字典...... – chikuba 2012-03-22 21:29:10

9

對於如此大量的這樣的屬性,我傾向於將數據存儲爲字典而不是單獨的屬性,我會將默認值存儲在屬性列表中NSDictionary對象可以使用prope初始化rty列表很容易。

如果使用的字典不符合您的口味,我仍然會將默認值存儲在屬性列表中,並且在指定的初始化程序中,我將遍歷屬性列表中的項目並將它們應用到self,價值編碼。您應該注意,這僅適用於可信數據,而不適用於用戶提供的數據,否則可能會被劫持以設置您不期望的其他屬性。

+1

+1,並且字典將更容易擴展並在以後更改。 – 2012-03-22 21:03:52

+0

但是如果你想在字典中存儲混合類型的屬性呢? – To1ne 2012-06-09 22:05:43

+0

@ To1ne這應該不成問題。 NSDictionary不強制類型安全。您可以存儲多種類型的對象。 – mtmurdock 2013-07-06 01:08:54

4

目標C中沒有內置Java類似的初始化合成屬性 ivars。但是,由於您的屬性看起來幾乎相同,所以您可能需要考慮將它們合成而不是合成它們。

當然,您需要編寫兩個看起來很嚇人的方法(here is a nice and clean example),但作爲回報,您可以使用統一的方式將屬性存儲爲NSMutableDictionary中的對象。這會打開幾個有趣的替代方案,但對於簡單的ivars卻不可用:你可以推遲你的屬性的初始化,直到它們被需要,你可以爲未設置的屬性提供默認值,或者你可以通過填充字典來初始化屬性「批發」鍵值。

+0

看起來很有意思,明天我要去看看,謝謝! – 2012-03-22 21:21:14

0

上面的字典建議是一個不錯的選擇。我有時使用專用的配置對象:

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

@implementation GoalKeepingAttributes 
@end 

等。如果需要,這個類可以有一個init方法,設置一堆值和默認值。

你也可以使用c-style結構,因爲這些只是基元。

這是真的,這只是推遲問題,從一類到配置類運動的初始化,但是:

  • 你必須用字典來做到這一點無論如何
  • 可以評論的配置設置
  • 最大的勝利:在配置類是強類型,這在編譯時捕獲錯誤,允許Xcode的代碼完成

你可以分裂的配置分爲不同的類型(守門員,技術和精神)。再次,它只是分解了問題,但這可以幫助保持專注。

0

另一種可能性是重寫屬性的默認getter。在你的getter中,你可以看看這些值是否被初始化,如果沒有,則返回你的默認值。 (這樣做是可以的某些屬性類型,但不是爲別人,清楚 - 你需要的默認值是一個表示沒有設置值。)

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函數中執行。

0

是的,你可以重寫getter以防在property被inited之前設置默認值。

例如,在.h文件中定義屬性:

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

和下.m文件執行覆蓋getter和設置默認值:

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