Проблема с синтаксисом точек - PullRequest
2 голосов
/ 26 февраля 2010
self.flipsidenavigationbar=aNavigationBar;  

зачем здесь нужна самость? (иначе он вылетает)

[flipsidenavigationbar pushnavigationietm........]; 

почему здесь самость не нужна?

обратите внимание, что flipsidenavigationbar - это iVar, объявленный как свойство и синтезированный.

спасибо

Alex

Ответы [ 3 ]

5 голосов
/ 26 февраля 2010

Необходимо помнить, что точка - это не просто синтаксис для доступа к iVar, а сокращение для вызова метода установки (или получения) ивара.

Это означает, что self.foo - это не то же самое, что просто foo (при условии, что foo - это ivar, объявленный как свойство). self.foo = значение; эквивалентно [self setFoo: value]; или значение = self.foo эквивалентно значению = [self foo]; Когда вы просто пишете foo, вы получаете доступ к foo напрямую без вызова метода.

Различие важно, потому что метод установки и получения обычно не просто присваивает или получает значение, а сохраняет его.

Итак, в вашем случае, когда вы пишете:

self.flipsidenavigationbar=aNavigationBar;

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

[self setFlipSideNavigationBar:aNavigationBar];

Если предположить, что свойство определено как копия или сохранено, то при вызове установщика будет сохранен NavigationBar. С другой стороны, если вы напишите:

self.flipsidenavigationbar = aNavigationBar;

Тогда вы просто устанавливаете значение self.flipsidenavigationbar напрямую, и aNavigationBar не сохраняется, что может вызвать сбой приложения при последующем доступе к NavigationBar

По другому вопросу:

[flipsidenavigationbar foo];

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

(Кстати: почему бы не использовать верблюжий чехол? Это действительно ранит глаза)

2 голосов
/ 26 февраля 2010

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

flipsidenavigationbar - указатель. Это просто указатель. Если вы говорите flipsidenavigationbar = aNavigationBar, вы заменяете один указатель другим указателем. Если вы сохранили предыдущий указатель, вы не отпускаете его. Вы не начинаете удерживать aNavigationBar. Это C. Здесь нет магии.

self.flipsidenavigationbar - это , а не простой указатель (несмотря на то, что он выглядит как структура). Это вызов метода. В качестве значения это [self flipsidenavigationbar]. Как значение, это [self setFlipsidenavigationbar:]. Эти код вызова. В большинстве случаев метод setFlipsidenavigationbar: включает освобождение старого значения и сохранение нового значения.

Есть несколько вещей, которые вы должны сделать, чтобы избежать путаницы:

  • Всегда, всегда используйте аксессоры для доступа к вашим иварам. Никогда не обращайтесь к ним напрямую.
  • Чтобы помочь в этом, никогда не определяйте, что ваши ивары имеют то же имя, что и ваш метод доступа. Таким образом, у вас будет ивар под названием _flipSideNavigationBar, который отображается на flipSideNavigationBar. Синтаксис для этого @synthesize foo = _foo.
  • Избегайте точечных обозначений, пока вы можете это делать. Те из нас, кто программировал в ObjC еще до точечной нотации, редко сталкиваются с серьезными проблемами, потому что мы интуитивно знаем, что он делает, и его немного легче набирать. Но это очень запутанно для новых разработчиков, и я обычно рекомендую избегать этого. Научитесь говорить [self foo] и [self setFoo:]. Код будет иметь больше смысла.
2 голосов
/ 26 февраля 2010

flipsidenavigationbar объявлено как тип свойства "сохранить"? Мое предположение относительно того, что происходит, заключается в следующем.

Метод точечного синтаксиса, который вы написали, эквивалентен

[self setFlipsidenavigationbar:aNavigationBar];

и этот вызов метода , вероятно , сохраняя объект aNavigationBar при его установке. Когда вы звоните

flipsidenavigationbar = aNavigationBar;

вы не сохраняете его, скорее всего, оно освобождается раньше, чем вы этого хотите, и вызывает ваш сбой.

Вы можете прочитать больше о точечный синтаксис в Obj-C, это, вероятно, поможет вам с такими проблемами в будущем.


На двух других постерах это сказано лучше, но очень важно помнить, что эти две строки:

self.myViewA = myViewB;
myViewA = myViewB;

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

я понимаю, что когда нужно установить / инициализировать свойство, которое вам нужно поставить там «я». но когда вы говорите это сделать что-то (в этом случае нажми) тебе не нужно я.

вы должны точно понимать, что происходит, чтобы вы знали, каковы последствия использования вашего точечного синтаксиса. Это сбивает с толку, я знаю, но на самом деле это не сложно, и все довольно быстро это понимают. Удачи!

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