In my project there is a xib file whose File Owner is set to a subclass of NSViewController. This xib file has a NSView with a View Based NSTableView inside. The NSViewController subclass implements the protocol NSTableViewDelegate and, in IB, the NSTableView’s delegate is connected to File’s Owner. When a view is created by bindings, the awakeFromNib method of the viewController gets called with this call stack:
#0 0x000000010000584b in -[TheViewController awakeFromNib]
#1 0x00007fff890f9bd8 in -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] ()
#2 0x00007fff893101d6 in -[NSNib _instantiateNibWithExternalNameTable:] ()
#3 0x00007fff89310c7a in -[NSNib instantiateNibWithExternalNameTable:] ()
#4 0x00007fff892bcac4 in -[NSTableRowData _unarchiveViewWithIdentifier:owner:] ()
#5 0x00007fff892be57b in -[NSTableView(NSTableViewViewBased) makeViewForTableColumn:row:] ()
#6 0x00007fff892be1b2 in -[NSTableRowData _addViewToRowView:atColumn:row:] ()
#7 0x00007fff892bde7f in -[NSTableRowData _addViewsToRowView:atRow:] ()
#8 0x00007fff892bc415 in -[NSTableRowData _addRowViewForVisibleRow:withPriorView:] ()
#9 0x00007fff892bc19a in -[NSTableRowData _addRowViewForVisibleRow:withPriorRowIndex:inDictionary:withRowAnimation:] ()
#10 0x00007fff892bb469 in -[NSTableRowData _unsafeUpdateVisibleRowEntries] ()
#11 0x00007fff892bb001 in -[NSTableRowData updateVisibleRowViews] ()
#12 0x00007fff892930fb in -[NSTableView viewWillDraw] ()
#13 0x00007fff89170bed in __22-[NSView viewWillDraw]_block_invoke_0 ()
#14 0x00007fff884d50b6 in __NSArrayEnumerate ()
#15 0x00007fff8917092d in -[NSView viewWillDraw] ()
#16 0x00007fff89170bed in __22-[NSView viewWillDraw]_block_invoke_0 ()
#17 0x00007fff884d50b6 in __NSArrayEnumerate ()
#18 0x00007fff8917092d in -[NSView viewWillDraw] ()
#19 0x00007fff891fb455 in -[NSScrollView viewWillDraw] ()
#20 0x00007fff89170bed in __22-[NSView viewWillDraw]_block_invoke_0 ()
#21 0x00007fff884d50b6 in __NSArrayEnumerate ()
#22 0x00007fff8917092d in -[NSView viewWillDraw] ()
#23 0x00007fff89170bed in __22-[NSView viewWillDraw]_block_invoke_0 ()
#24 0x00007fff884d50b6 in __NSArrayEnumerate ()
#25 0x00007fff8917092d in -[NSView viewWillDraw] ()
#26 0x00007fff89247e0d in -[NSBox viewWillDraw] ()
#27 0x00007fff89170bed in __22-[NSView viewWillDraw]_block_invoke_0 ()
#28 0x00007fff884d50b6 in __NSArrayEnumerate ()
#29 0x00007fff8917092d in -[NSView viewWillDraw] ()
#30 0x00007fff89170bed in __22-[NSView viewWillDraw]_block_invoke_0 ()
#31 0x00007fff884d50b6 in __NSArrayEnumerate ()
#32 0x00007fff8917092d in -[NSView viewWillDraw] ()
#33 0x00007fff89170bed in __22-[NSView viewWillDraw]_block_invoke_0 ()
#34 0x00007fff884d50b6 in __NSArrayEnumerate ()
#35 0x00007fff8917092d in -[NSView viewWillDraw] ()
#36 0x00007fff89170bed in __22-[NSView viewWillDraw]_block_invoke_0 ()
#37 0x00007fff884d50b6 in __NSArrayEnumerate ()
#38 0x00007fff8917092d in -[NSView viewWillDraw] ()
#39 0x00007fff8916ff84 in -[NSView _sendViewWillDrawInRect:clipRootView:] ()
#40 0x00007fff8913c3f1 in -[NSView displayIfNeeded] ()
#41 0x00007fff891f93f8 in -[NSWindow _reallyDoOrderWindow:relativeTo:findKey:forCounter:force:isModal:] ()
#42 0x00007fff891f8a18 in -[NSWindow _doOrderWindow:relativeTo:findKey:forCounter:force:isModal:] ()
#43 0x00007fff891f85ff in -[NSWindow orderWindow:relativeTo:] ()
#44 0x00007fff890f9c96 in -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] ()
#45 0x00007fff890d8b7d in loadNib ()
#46 0x00007fff890d80a9 in +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] ()
#47 0x00007fff890d7ede in -[NSBundle(NSNibLoading) loadNibNamed:owner:topLevelObjects:] ()
#48 0x00007fff890d7cbe in +[NSBundle(NSNibLoading) loadNibNamed:owner:] ()
#49 0x00007fff890d447f in NSApplicationMain ()
#50 0x0000000100001432 in main
The awakeFromNib method shouldn’t be called only after the viewController is instantiated?
It seems like from my experience that the
File's Ownerof any xib document will receive an-awakeFromNibmessage whenever a new view is loaded from that xib file. This would, as you noticed, occur when view-based table views create new rows from the xib file.And I know of no way to stop that from happening, except to maybe keep track of how many times you’ve called
awakeFromNiband execute the initialization code only the first time.Or, better yet, put your initialization logic in another method that has a more solid timing – e.g. in
-loadView, after the call tosuper. I do something like: