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

Какая разница между синтаксисом точек и синтаксисом квадратной скобки?

Я прохожу через некоторые пошаговые руководства fpr Objective-C, и я добрался до многих мест, где я поднял брови. Я бы с удовольствием их убрал.

  • Есть ли принципиальная разница в отправке сообщений и вызове метода? Objective-C позволяет мне делать оба: object.message дает тот же результат, что и [object message]. Я думаю, возможно, что вложенные сообщения не могут быть созданы с использованием стратегии оператор-точка?

  • Я создал объект NSArray, теперь я собираюсь распечатать результаты для этого, используя NSEnumerator:

    id myObject = [object objectEnumerator];

    при повторении и печати результатов цикла while. Тип myObject - id, что означает, что он разрешен во время выполнения, а не во время компиляции. Я очень четко знаю, какие объекты хранятся в моем NSArray -they NSString s-so, изменив тип myObject на NSString * myObject, он работает отлично. Тем не менее, я экспериментировал и обнаружил, что myObject может быть любого типа, будь то NSString или NSArray или NSEnumerator, и любая из них работает просто отлично, отлично повторяя объект NSArray и получая тот же Результаты. Что с этим?

4b9b3361

Ответ 1

Я не уверен, какое различие вы пытаетесь сделать между "отправкой сообщений" и "вызовом метода", поскольку они представляют собой два способа описания одного и того же. Точечный синтаксис - это просто ярлык для вызова getters и seters, то есть:

[foo length]
foo.length

точно такие же, как:

[foo setLength:5]
foo.length = 5

Обычно вы используете только точечный синтаксис, когда используете геттеры и сеттеры; используйте синтаксис квадратной скобки для всех ваших вызовов других методов.

Для вашего второго вопроса: так работает динамический ввод. Все объявления типа, введенные в код, являются подсказками для компилятора; ваши вызовы методов Objective-C всегда будут работать, пока объекты реагируют на них.

Ответ 2

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

Я думаю, что намерение Apple состоит в том, чтобы показать аксессурам как деталь реализации, о которой вы не должны беспокоиться. Даже когда они могут вызывать побочные эффекты (из-за некоторого дополнительного кода в аксессуре), они обычно этого не делают, поэтому абстракция несовершенна, но стоит того (ИМХО). Еще одним недостатком использования точечной нотации является то, что вы действительно не знаете, есть ли за ней структура или объединение (что в отличие от отправки сообщений, никогда не вызывает побочные эффекты при назначении). Возможно, Apple должна была использовать что-то отличное от точки. *shrugs*

Я думаю, возможно, что вложенные сообщения не могут быть созданы с использованием стратегии оператор-точка?

Точечная нотация может использоваться для вложенных вызовов, но учитывайте следующее:

shu.phyl.we.spaj.da
[[[[[shu]phyl]we]spaj]da]

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

Ответ 3

1: Ваша терминология неверна. Оператор точки не является "вызовом метода", другой операцией. Это просто отличный внешний вид для отправки сообщений. Нет никакой разницы между [x y] и x.y. Точечный синтаксис может принимать только один аргумент, поскольку он предназначен для использования только для доступа к свойствам.

2: Статический (время компиляции) объекта не влияет на его поведение во время выполнения. Ваш объект по-прежнему является NSEnumerator, даже если вы называете его чем-то другим.

Ответ 4

1) Они оба отправляют сообщения, просто разные синтаксисы. [object message] - традиционный синтаксис, object.message - это "точечное обозначение", но означает точно то же самое. Вы можете делать некоторые виды вложенности с точечной нотацией, но вы не можете ничего делать с методами, которые принимают сложные аргументы. В общем, старые программисты Obj-C не используют точечную нотацию, кроме простых вызовов доступа. ИМХО.

2) Среда исполнения действительно умна и может понять ее на лету. Тип заливки указателей на самом деле является лишь ключом к компилятору, чтобы вы знали, когда перепутались. Это не означает ничего (в этом случае), когда сообщение отправляется в массив для получения значения.

Ответ 5

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

  • id - это в основном указатель на что угодно. Это требует некоторого привыкания, но это основа того, как Objective-C обрабатывает динамическую типизацию объектов. Когда NSLog() попадает в спецификатор формата %@, он отправляет сообщение description объекту, который должен заменить токен (это реализовано в суперклассе NSObject) и может быть переопределено в подклассе, чтобы получить желаемый выход).

В будущем, когда вы это сделаете, вам может быть проще сделать что-то вроде этого:

for (NSString *s in YourNSArrayInstance) //assuming they are NSStrings as you described
{
    NSLog(@"%@", s);
}

Или просто просто:

for (NSString *s in YourNSArrayInstance) //assuming they are NSStrings as you described
    NSLog(@"%@", s);

В конце концов вы научитесь как отправлять сообщения.