Точечная нотация Obj-c для чтения свойств: почему я не могу объединить ее таким образом?

#objective-c #properties

#objective-c #свойства

Вопрос:

у меня есть эта строка кода:

 [[[EntitlementsManager instance] entitlements] objectAtIndex:indexPath.row];
  

Почему это не будет работать следующим образом:

 [EntitlementsManager.instance.entitlements objectAtIndex:indexPath.row];
  

Мне кажется, что это должно сработать? Я немного смущен тем, почему это не компилируется.

К вашему СВЕДЕНИЮ, EntitlementsManager, ‘instance’ — это метод ‘ ‘ для возврата его синглтона, а ‘entitlements’ — это свойство NSArray.

-редактировать: Для тех, кто почему-то говорит, что это не работает, потому что ‘instance’ — это статический метод ‘ ‘, тогда почему следующее работает просто отлично? Я действительно заинтригован:

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return EntitlementsManager.instance.entitlements.count;
}
  

-правка2: как ни странно, это действительно работает:

 ... = [[EntitlementsManager instance].entitlements objectAtIndex:indexPath.row];
  

Комментарии:

1. точечная нотация — это синтаксический сахар.

2. Какую фактическую ошибку выдает компилятор? Что за объявление в EntitlementsManager?

3. Фактическая ошибка — «ожидаемый идентификатор».

4. Да, я воспроизвел вашу ошибку как в GCC, так и в Clang / LLVM. Хотя не уверен, почему это происходит.

5. Да, это действительно должно сработать, но компиляторы в этом случае ведут себя неправильно. Обратите внимание, что работает следующее: blahblah = EntitlementsManager.instance.entitlements; , IIRC.

Ответ №1:

Возможно, анализатор запутался, когда увидел, что тип появляется слева от . внутри вызова метода Obj-C. Например, если грамматика

 '[' Type   methodAndArguments ']'
  

существует, тогда оно будет проанализировано перед распознаванием a '.' b , и поскольку .instance ... это не ожидаемая конструкция methodAndArguments, компилятор завершит работу с ошибкой. Поскольку Type.method синтаксис dot не является ожидаемым использованием, компилятор может не поддерживать его или даже допустить синтаксическую ошибку при его использовании в будущем.

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

 [[EntitlementsManager instance].entitlements objectAtIndex:0]
  

или переместить это выражение за скобки:

 NSArray* entitlements = EntitlementsManager.instance.entitlements;
[entitlements objectAtIndex:0];
  

или принудительно '[' Type methodAndArguments ']' не сопоставлять:

 [(nil, EntitlementsManager.instance.entitlements) objectAtIndex:0]
  

Комментарии:

1. Вау, звучит сложно. Я просто отнесу это к ошибке / странности компилятора.

Ответ №2:

Попробуйте этот способ

[(EntitlementsManager.instance.entitlements) objectAtIndex:indexPath.row];

может сработать

Комментарии:

1. Не работает, я получаю «ожидается)», хотя это, безусловно, есть.