Задача C назначение вызывающего сеттера? - PullRequest
0 голосов
/ 27 марта 2020

У меня есть поле:

@interface SomeClass : NSObject

@property(nonatomic, nullable) BOOL questionCreated;
@property(nonatomic, nullable) NSString question;

Если я создаю сеттер для вопроса, например:

-(void)setQuestion:(NSString)question {
  _question = question;
  _questionCreated = YES;
}

А затем в другом файле, предположим, у меня есть экземпляр SomeClass, называемый someClassInstance.

Если я сделаю что-то вроде:

someClassInstance.question = "manually set question"

, к моему удивлению, я вижу, что someClassInstance.questionCreated теперь также имеет значение YES, что заставляет меня поверить, что оно вызывает установщик непосредственно, если я делаю someClassInstance.question. Почему это так и как я могу принудительно установить только одно поле?

1 Ответ

2 голосов
/ 27 марта 2020

Эта строка кода:

someClassInstance.question = @"manually set question";

совпадает с этой строкой кода:

[someClassInstance setQuestion:@"manually set question"];

И под «тем же самым» я имею в виду первое, преобразованное в последний во время компиляции. Вот что означает «точечная нотация» в Objective- C.

(Примечание: когда этот синтаксис был добавлен к Obj C в 2007 году, он был довольно спорным, особенно потому, что он вызывает путаницу что вы столкнулись. Я не был поклонником в то время. Как и большинство людей, однако, я очень привык к сахару, и его легче набирать, поэтому вы привыкаете к нему. Но ваша путаница не Удивительно.)

Как правило, внешние объекты не должны беспокоиться о внутренних деталях установщика. Если они есть, что-то неправильно спроектировано (я бы, вероятно, переименовал setQuestion во что-то другое).

Но другой подход заключается в предоставлении прямого установщика. Это чаще всего префикс «примитив», такой как:

- (void)setPrimitiveQuestion:(NSString *)question {
    _question = question;
}

А затем вы строите setQuestion поверх этого:

- (void)setQuestion:(NSString *)question {
    [self setPrimitiveQuestion: question];
    self.questionCreated = @YES;
}

К вашему актуальному вопросу, да, это возможно делать именно то, что вы предлагаете. Как правило, это дурной тон, но если вам это действительно нужно, вы можете напрямую подключиться к ивару и изменить его:

someClassInstance->_question = @"...";

Но не делайте этого, если вы действительно не знаете, что делаете.

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