OSX Cocoa - Creating a Custom cell view causes access violation

I created a table view with a custom nstablecellview - I added 2 additional fields to the view. I’m making a list with a view that is similar to an IOS table. I’m planning on having iPad and OSX versions. I have attached a sample application that demonstrates the problem. If I set the Title and Number fields, they display properly but I get an access violation immediately after the table is populated. Since I cannot debug this problem, I don’t know what is happening. The same thing happens in my actual application but I created a small demo to illustrate the problem.

We’ll have a look, but what keeps you from debugging the app? (i recommend Instruments in Zombies mode for bugs like these).

hm, i’m running your test app, and i see no crashes, and Instruments reports nothing suspicious, except memory load going up every time i click Click Me.

Oh, nevermind, found the uncommented code now. i can repdoucde the AV, and Instruments does report a Zombie:

# Event Type ∆ RefCt RefCt Timestamp Responsible Library Responsible Caller
0 Malloc +1 1 00:00.853.795 Foundation _decodeObjectBinary
7 Retain +1 2 00:00.854.419 Foundation _decodeObjectBinary
8 Retain +1 3 00:00.854.435 Foundation -[NSKeyedUnarchiver _replaceObject:withObject:]
9 Release -1 2 00:00.854.436 Foundation _decodeObjectBinary
10 Retain +1 3 00:00.854.438 Foundation _decodeObjectBinary
11 Autorelease 00:00.854.449 Foundation _decodeObject
12 Retain +1 4 00:00.854.633 Foundation _decodeObjectBinary
13 Retain +1 5 00:00.854.639 Foundation -[NSKeyedUnarchiver _decodeArrayOfObjectsForKey:]
14 Release -1 4 00:00.854.643 Foundation -[NSKeyedUnarchiver _decodeArrayOfObjectsForKey:]
15 Retain +1 5 00:00.854.651 Foundation -[NSArray(NSArray) initWithCoder:]
16 Release -1 4 00:00.854.664 Foundation _decodeObject
17 Release -1 3 00:00.854.674 Foundation _decodeObject
30 Retain +1 4 00:00.855.173 Foundation _decodeObjectBinary
31 Retain +1 5 00:00.855.216 Foundation -[NSKeyedUnarchiver _decodeArrayOfObjectsForKey:]
32 Release -1 4 00:00.855.227 Foundation -[NSKeyedUnarchiver _decodeArrayOfObjectsForKey:]
33 Retain +1 5 00:00.855.252 Foundation -[NSArray(NSArray) initWithCoder:]
34 Release -1 4 00:00.855.277 Foundation _decodeObject
Retain (2) +2 00:00.855.306 Foundation _decodeObjectBinary
Retain (2) +2 00:00.855.326 Foundation -[NSKeyedUnarchiver _decodeArrayOfObjectsForKey:]
Release (2) -2 00:00.855.335 Foundation -[NSKeyedUnarchiver _decodeArrayOfObjectsForKey:]
Retain (2) +2 00:00.855.363 Foundation -[NSArray(NSArray) initWithCoder:]
Release (2) -2 00:00.855.389 Foundation _decodeObject
45 Retain +1 7 00:00.855.466 Foundation __NSMapTableCallback
Retain (2) +2 00:00.855.467 Foundation __NSMapTableCallback
48 Retain +1 10 00:00.855.511 Foundation _decodeObjectBinary
49 Retain +1 11 00:00.855.535 Foundation -[NSKeyedUnarchiver _decodeArrayOfObjectsForKey:]
50 Release -1 10 00:00.855.552 Foundation -[NSKeyedUnarchiver _decodeArrayOfObjectsForKey:]
51 Retain +1 11 00:00.855.579 Foundation -[NSArray(NSArray) initWithCoder:]
52 Release -1 10 00:00.855.608 Foundation _decodeObject
57 Release -1 9 00:00.856.127 Foundation -[NSKeyedUnarchiver dealloc]
58 Release -1 8 00:00.856.150 Foundation -[NSKeyedUnarchiver dealloc]
Release (4) -4 00:00.856.208 Foundation -[NSKeyedUnarchiver dealloc]
63 Release -1 3 00:00.856.404 Foundation __NSMapTableCallback
Release (2) -2 00:00.856.411 Foundation __NSMapTableCallback
66 Retain +1 2 00:00.856.562 CocoaApplication4 -[ItemInfoCell TitleField]
67 Autorelease 00:00.856.563 CocoaApplication4 -[ItemInfoCell TitleField]
68 Autorelease 00:00.856.566 CocoaApplication4 -[ItemInfoCell TitleField]
69 Retain +1 3 00:00.856.567 CocoaApplication4 -[MainWindowController tableView:viewForTableColumn:row:]
70 Release -1 2 00:00.856.591 CocoaApplication4 -[MainWindowController tableView:viewForTableColumn:row:]
73 Retain +1 3 00:00.856.748 AppKit -[NSView _recursiveSetDefaultKeyViewLoop]
80 Release -1 2 00:01.162.874 AppKit -[NSView _layoutSubtreeHeedingRecursionGuard:]
Release (2) -2 00:01.162.968 AppKit -[NSView _layoutSubtreeHeedingRecursionGuard:]
83 Zombie -1 00:01.163.345 AppKit -[NSWindow(NSConstraintBasedLayout) _updateLayoutDependentMetricsIfNeeded]

Hm. very weird. the problem goes away if i make “TitleField” & co string instead of weak. but that does not sound like this is the root problem, just a symptom.

since it IS an NSTextField that gets zombied (accessed after it has been released), my money is on something going screwy with the reference counting in tableView:viewForSolumn:row:.

Coincidentally, accessing a weak property like this is very unsafe (but not cause of the zombie), youn need to expect weak properties to go nil on you at any time (even if unlikely in this scenario, so recommended practise is to assign them to a string local var, check for nil, and then use them, ie:

var ft := myCell.textField;
if assigned(tf) then tf.stringValue := x

OR at the very least

myCell.textField:stringValue := x;

On the plus side, this issue DOES reproduce with something as simple as

method MainWindowController.tableView(tableView: NSTableView) viewForTableColumn(tableColumn: NSTableColumn) row(row: NSInteger): NSView;
begin
var myCell := tableView.makeViewWithIdentifier(‘SimpleItemInfoCell’) owner(self);
myCell.TitleField.stringValue := ‘x’;
result := myCell;
end;

so i’ll log to have this looked at as a possible compiler codegen bug with ARC. While the retain/release history is long winded, it does seem that the only retaines/releases originating from MainWindowController (ie your own code, above-mentioned method) are these:

# Event Type ∆ RefCt RefCt Timestamp Responsible Library Responsible Caller 66 Retain +1 2 00:01.224.976 CocoaApplication4 -[ItemInfoCell TitleField] 67 Autorelease 00:01.224.977 CocoaApplication4 -[ItemInfoCell TitleField] 68 Autorelease 00:01.224.980 CocoaApplication4 -[ItemInfoCell TitleField] 69 Retain +1 3 00:01.224.980 CocoaApplication4 -[MainWindowController tableView:viewForTableColumn:row:] 70 Retain +1 4 00:01.224.981 AppKit -[NSTableRowData _addViewToRowView:atColumn:row:] 71 Release -1 3 00:01.225.010 CocoaApplication4 -[MainWindowController tableView:viewForTableColumn:row:] 72 Release -1 2 00:01.225.011 CocoaApplication4 -[MainWindowController tableView:viewForTableColumn:row:]

and they do seem unbalanced (which does seam to indicate an ARC compiler bug)

bugs://63232: Nougat: Possible ARC reference counting issue when accessing weak property

You are correct, making them Strong works but not sure why.

“Coincidentally, accessing a weak property like this is very unsafe (but not cause of the zombie), youn need to expect weak properties to go nil on you at any time (even if unlikely in this scenario, so recommended practise is to assign them to a string local var, check for nil, and then use them, ie:”

I’ve been comparing xcode with oxygene to see the differences. When working with view controllers in xcode, the default storage appears to be strong when creating properties with the Assistant Editor.

If I understand this correctly, the “form” creates an instance of itself including all the sub-views (buttons, fields, etc). Then our own connected variables are declared as “weak” in order “reference” the sub-views but not take ownership. Correct? But if this is the case, I don’t know why any Outlet would be declared as Strong.

Indeed, outlets usually re declared weak. assuming that your view controller is holding on to the root view hierarchy, that is keeping all your views alive, so strong outlets are not needed.

i guess the distinction is mostly academic in this case, but there are (easy to come across) scenarios where strong outlets can cause retain cycles, so i guess its just considered best to stay on the safe (weak) side for outlets, as common pattern.