Objective-C установить значение по умолчанию для свойства - PullRequest
28 голосов
/ 23 марта 2012

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

Ответы [ 7 ]

47 голосов
/ 23 марта 2012

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

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

И вызовите это так:

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

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

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

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

9 голосов
/ 23 марта 2012

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

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

4 голосов
/ 23 марта 2012

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

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

1 голос
/ 14 января 2018

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

Например, определить свойство в файле .h:

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

и переопределить метод получения и установитьзначение по умолчанию в реализации в файле .m:

@implementation MySegmentedControl    
-(CGFloat) systemFontOfSize
{
    return _systemFontOfSize ? _systemFontOfSize : 17.0f;
}    
@end
0 голосов
/ 08 июля 2016
- (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, если объект является представлением.Если это не вид, вы можете сделать это в функции инициализации, на мой взгляд.

0 голосов
/ 18 января 2013

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

0 голосов
/ 08 ноября 2012

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

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

@implementation GoalKeepingAttributes
@end

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

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

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

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

Вы можете разделить конфигурации на различные типы (Цели, Технический и Ментальный). Опять же, это просто разделяет проблему, но это может помочь сосредоточиться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...