Почему свойство contentView NSWindow типа id? - PullRequest
5 голосов
/ 06 февраля 2012

Почему свойство contentView класса NSWindow имеет тип id вместо NSView

Это не имеет смысла для меня, почему contentView должен быть чем-то отличным от NSView подкласса.

Так что в моем случае я должен был напечатать его так, чтобы получить доступ к его фрейму:

NSView *contentView = self.window.contentView; // returns an `id`
CGRect frame = contentView.frame

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

CGRect frame =  self.window.contentView.frame; // This does not compile

Ответы [ 3 ]

9 голосов
/ 06 февраля 2012

Это, вероятно, исторический.Objective-C поддерживает строгую типизацию, но также поддерживает «типизацию утки», при которой вам все равно, * класс объекта, вы заботитесь о том, на какие сообщения он отвечает (т.е. еслиэто похоже на утку, и это крякает как утка, это, вероятно, утка).Вам разрешено вводить каждый указатель объекта как id и отправлять любые сообщения.Действительно, получателю не нужно реализовывать методы для любого сообщения, которое он получает в любом случае: он также может переслать сообщение другому объекту.

В Application Kit - предшествующей платформе GUIв OpenStep и Cocoa - почти все объекты использовались посредством утки.Вот (частичный) интерфейс для Window из версии 3.2 комплекта приложений.

@interface Window : Responder
{
  NXRect frame;
  id contentView;
  id delegate;
  id firstResponder;
  id lastLeftHit;
  id lastRightHit;
  id counterpart;
  id fieldEditor;
  int winEventMask;
  int windowNum;
  float backgroundGray;
  //some bit masks indicating whether the window is visible, is key etc.
}
-contentView;
-setContentView:aView;
//more methods
@end

Обратите внимание, что contentView ivar определен как id, и что все типы вметоды доступа тоже неявно определены как id (поэтому -setContentView: возвращает объект: вероятно, Window instance self).Вот как выглядела большая часть кода Objective-C в начале 1990-х: Application Kit, вероятно, был большинством кода Objective-C в начале 1990-х годов.

NSWindow был представлен в первой версии AppKit- структура GUI в том, что стало Какао, еще в 1994 году. В AppKit обычно используются более строгие объявления типов, чем в Application Kit, но это не соблюдается жестко.Действительно, это может даже быть случай, когда AppKit NSWindow содержит код из Window Application Kit, и что этот contentView ivar не был обновлен в изменении.

Действительно, жесткое требование соответствия типов в Objective-C переменные сравнительно недавно.Большая часть строгости была введена либо через объявления свойств (которые строго типизированы, за исключением того, что C существует и поддерживает приведение), либо через изменение протоколов, которое допускает необязательные методы, что позволяет строго типизировать объекты делегирования.

2 голосов
/ 06 февраля 2012

Тот факт, что -[NSWindow contentView] имеет тип id, вероятно, является пережитком ранних дней Какао и Objective-C.

В любом случае: предупреждения компилятора являются результатом синтаксиса стиля свойств, который выиспользуют для отправки сообщений.В Какао (в отличие от Какао-Touch) window, contentView и frame не являются свойствами их классов.Это означает, что вы должны использовать обычный синтаксис отправки сообщений:

CGRect frame = [[[self window] contentView] frame];

Это будет работать без предупреждений компилятора.

0 голосов
/ 06 февраля 2012

Это для динамического набора текста.A NSWindow на самом деле не волнует, действительно ли он contentView является NSView, если он отвечает на селекторы, которые он отправляет.Таким образом, теоретически вы можете создать свой собственный класс, который не наследуется от NSView для отображения контента, и компилятор не захлебнется.

...