簡體   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