Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>So far I have not found any evidence of trouble, so I'm comfortable adopting "Method 5" that I outlined in my question update, which I'll duplicate here with some additional explanation:</p> <pre><code>// An additional constructor public ImageAndTextCell (IntPtr handle) : base(handle) { } // Cocoa Selectors static IntPtr selRetainCount = Selector.GetHandle("retainCount"); static IntPtr selCopyWithZone = Selector.GetHandle("copyWithZone:"); static List&lt;ImageAndTextCell&gt; _refPool = new List&lt;ImageAndTextCell&gt;(); // Helper method to be called at some future point in managed code to release // managed instances that are no longer needed. public void PeriodicCleanup () { List&lt;ImageAndTextCell&gt; markedForDelete = new List&lt;ImageAndTextCell&gt; (); foreach (ImageAndTextCell cell in _refPool) { uint count = Messaging.UInt32_objc_msgSend (cell.Handle, selRetainCount); if (count == 1) markedForDelete.Add (cell); } foreach (ImageAndTextCell cell in markedForDelete) { _refPool.Remove (cell); cell.Dispose (); } } // Overriding the copy method [Export("copyWithZone:")] public virtual NSObject CopyWithZone(IntPtr zone) { IntPtr copyHandle = Messaging.IntPtr_objc_msgSendSuper_IntPtr(SuperHandle, selCopyWithZone, zone); ImageAndTextCell cell = new ImageAndTextCell(copyHandle) { Image = Image, }; _refPool.Add(cell); return cell; } </code></pre> <p>By invoking the copyWithZone: selector on the base object (via SuperHandle), the underlying Cocoa subsystem will clone the unmanaged object and give back the handle to it, with its retain count already set to 1 (standard obj-c copy convention). It's then possible to construct the derived C# object with the cloned object handle, so the cloned instance becomes the backing object. Then it's a simple matter of cloning any managed C# goodies that belong to the derived type.</p> <p>As ta.speot.is pointed out, it's also necessary to hold onto a reference of the managed type somewhere. Without the reference, the object is a candidate for garbage collection at the end of the method. The unmanaged portion of the object is safe on return because it has a positive retain count from the call to the copy selector. I've chosen to store references in a static List, and then periodically call a cleanup method from other parts of code which will traverse the list, check if the corresponding unmanaged objects have any other owners, and dispose the objects if not. Note that I'm checking for a count of 1 instead of 0, because our copied object was actually retained twice: once by the copy selector, and once by the NSObject constructor. The Monomac runtime system will take care of disposing the unmanaged object when the managed side is disposed/collected.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload