Why is the contentView property of NSWindow a type identifier?

Why the contentView property of the NSWindow class of id type instead of NSView

It doesn't make sense to me why the contentView should be anything other than a subclass of NSView .

So, in my case, I had to enter it so as to access its frame:

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

Instead, the compiler does not like:

 CGRect frame = self.window.contentView.frame; // This does not compile 
+4
source share
3 answers

This is probably historical. Objective-C supports strong typing, but also supports duck typing, in which you don’t care which class the object is, you care about what messages it responds to (i.e. if it looks like a duck and it bows like duck, it's probably a duck). You are allowed to enter each object pointer as id and send any messages. Indeed, the recipient does not need to implement methods for any message that he receives anyway: he can simply redirect the message to another object.

In the Application Kit - the previous GUI for OpenStep and Cocoa - almost all objects were used with duck printing. Here's the (partial) interface for Window from version 3.2 of the Application Kit.

 @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 

Note that the contentView ivar is defined as id and that all types in access methods are implicitly defined as id too (therefore, -setContentView: returns an object: possibly a Window instance of self ). What Objective-C code looked like in the early 1990s: The Application Kit was probably the most Objective-C code in the early 1990s.

NSWindow was introduced in the first version of AppKit - the GUI in what Cocoa became in 1994. AppKit typically uses more stringent type declarations than the Application Kit, but this is not strictly enforced. In fact, it may even be that AppKit NSWindow contains code from the Application Kit Window and that this contentView contentView has not been updated in a change.

Indeed, the stringent requirement of type matching in Objective-C variables is relatively small. Most of the rigor was introduced either through property declarations (which are strongly typed, except that C exists and supports casting), or by changing protocols that allow optional methods, which allows you to strictly type delegate objects.

+8
source

The fact that -[NSWindow contentView] is of type id is probably relic from the early days of Cocoa and Objective-C.

In any case: compiler warnings are the result of a property style syntax that you use to send messages. In Cocoa (unlike Cocoa -Touch) window , contentView and frame are not properties of their classes. This means that you should use the usual syntax for sending messages:

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

This will work without compiler warnings.

+2
source

This is for dynamic input. A NSWindow does not matter if it contentView is a contentView is an NSView if it responds to the selector that it sent. That way, you could theoretically create your own class that does not inherit from NSView to display content, and the compiler does not suffocate.

-one
source

Source: https://habr.com/ru/post/1395057/


All Articles