Подтвердить что ты не робот

Objective-C установить значение по умолчанию для свойства

Я создаю приложение, и у меня есть класс с довольно много свойств, и мне было интересно, можно ли дать им значение по умолчанию. Потому что, если я создаю метод 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;}
}
4b9b3361

Ответ 1

Я никогда не видел этого поведения раньше, но я уверен, что это то, на что начинается init, когда выделяется объект, который устанавливает переменные и инициализирует объект.

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

И вызов выглядит так:

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

Обратите внимание, что вы можете иметь более одной функции init, которая позволяет вам иметь несколько разных наборов значений по умолчанию.

То, что @synthesize делает, сообщает прекомпилеру, что он должен генерировать код для set/get, а не устанавливать значение свойства. "=" Просто сообщает прекомплекторуемому, что, хотя имя переменной и свойство не совпадают, они должны быть связаны.

Кроме того, как личное мнение (вообще не доведенное до вопроса), этот объект кажется большим, и вы можете каким-то образом разбить его или сделать то, что предложили другие люди. Может быть, этот класс может наследовать от нескольких других классов, чтобы дать ему разные свойства, которые ему нужны? Как я уже сказал, это просто предложение, так как я не знаю, как выглядит ваш другой код:)

Ответ 2

Для такого большого количества таких атрибутов я бы склонен хранить данные как словарь, а не отдельные свойства, и я бы сохранил значения по умолчанию в списке свойств. NSDictionary объекты могут быть легко инициализированы списком свойств.

Если использование словаря не соответствует вашим вкусам, я бы сохранил значения по умолчанию в списке свойств, а в назначенном инициализаторе я бы перебирал элементы в списке свойств и применял их к self с помощью ключа -значение. Следует отметить, что это относится только к доверенным данным, а не к данным, предоставленным пользователем, поскольку в противном случае его можно было бы захватить, чтобы установить другие свойства, которых вы не ожидаете.

Ответ 3

В Objective C. нет встроенного Java-подобного способа инициализации синтезированных свойств или ivars. Однако, поскольку ваши свойства выглядят почти одинаковыми, вы можете захотеть сделать их @dynamic вместо их синтеза.

Конечно, вам нужно будет написать два страшных метода (вот вам хороший и чистый пример), но взамен вы получаете единый способ хранения ваших свойств как объектов внутри NSMutableDictionary. Это открывает несколько интересных альтернатив, недоступных для простых иваров: вы можете отложить инициализацию своих свойств до тех пор, пока они не понадобятся, вы можете предоставить значения по умолчанию для неустановленных свойств или вы можете инициализировать свои свойства "оптом", заполнив словарь значениями для их ключи.

Ответ 4

Предлагаемое выше предложение словаря является хорошим. Я иногда использовал выделенные объекты конфигурации:

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

@implementation GoalKeepingAttributes
@end

и т.д.. При необходимости этот класс может иметь метод init, который устанавливает набор значений и значений по умолчанию.

Возможно, вы также можете использовать структуру c-style, так как это всего лишь примитивы.

Верно, что это просто откладывает проблему, перемещая инициализацию из одного класса в класс конфигурации, но:

  • вам все равно придется делать это со словарем
  • вы можете прокомментировать настройки конфигурации
  • наибольшая победа: класс конфигурации строго типизирован, который ловит ошибки во время компиляции, позволяет завершить код кода x

Вы можете разделить конфигурации на разные типы (Goalkeeping, Technical и Mental). Опять же, это просто расщепление проблемы, но это может помочь сосредоточить внимание.

Ответ 5

Еще одна возможность - переопределить свойства getter по умолчанию. В ваших геттерах вы можете посмотреть, были ли инициализированы значения и, если нет, вернуть значение по умолчанию. (Это будет работать для некоторых типов свойств, но не для других, ясно - вам нужно, чтобы значение по умолчанию было таким, которое указывает, что значение не было установлено.)

Ответ 6

- (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 по моему мнению.