Bug 27752 - Garbage collector collects ui elements still on the display stack
Summary: Garbage collector collects ui elements still on the display stack
Alias: None
Product: iOS
Classification: Xamarin
Component: XI runtime ()
Version: master
Hardware: Macintosh Mac OS
: Normal normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2015-03-08 01:45 UTC by Jason Slater
Modified: 2015-03-23 09:17 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Jason Slater 2015-03-08 01:45:15 UTC
Created a UIView subclass containing a UIScrollView subview which contained a number of custom UITextView and UIImageView children.

After updating to the unified API the app began crashing when attempting to access the Subviews array of the UIScrollView. The error stated that FPTextView (the custom UITextView class) could not be marshalled because it did not have a constructor which accepted an IntPtr.

Please see http://forums.xamarin.com/discussion/comment/108020
Comment 1 Rolf Bjarne Kvinge [MSFT] 2015-03-09 07:52:10 UTC
Can you attach your project so that we can try to reproduce this?
Comment 2 Jason Slater 2015-03-19 11:05:24 UTC
The project is just under 500mb, and I don't have a place to upload it to share. Is there another way I can get it to you?
Comment 3 Rolf Bjarne Kvinge [MSFT] 2015-03-20 05:00:52 UTC
Customers usually use Dropbox (or a similar service) to ship us big apps.
Comment 5 Rolf Bjarne Kvinge [MSFT] 2015-03-20 20:03:26 UTC
Can you get your version information from Xamarin Studio's about menu (click on the Details button)?
Comment 6 Jason Slater 2015-03-21 16:54:32 UTC
Xamarin Studio
Version 5.8 (build 443)
Installation UUID: bfb79e0c-6ac3-429a-a4c1-192bb9281d60
	Mono 3.12.1 ((detached/b7764aa)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 312010000

Apple Developer Tools
Xcode 6.2 (6776)
Build 6C131e

Version: (Indie Edition)
Hash: ccfcd59
Build date: 2015-03-10 02:20:32-0400

Version: (Indie Edition)
Android SDK: /Users/jasoncslater/Library/Developer/Xamarin/android-sdk-mac_x86
	Supported Android versions:
		2.1   (API level 7)
		2.2   (API level 8)
		2.3   (API level 10)
		3.1   (API level 12)
		4.0   (API level 14)
		4.0.3 (API level 15)
		4.1   (API level 16)
		4.4   (API level 19)
Java SDK: /usr
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)

Xamarin Android Player
Not Installed

Not Installed

Build Information
Release ID: 508000443
Git revision: 73883239470cbe8e261c94d95f7c3d0452fd393b
Build date: 2015-03-10 07:22:51-04
Xamarin addins: a2ff7b617f09d9c45d8bbf3d010b5db0d7d36100

Operating System
Mac OS X 10.10.3
Darwin Vallista.local 14.3.0 Darwin Kernel Version 14.3.0
    Thu Jan 22 23:54:42 PST 2015
    root:xnu-2782.20.26~5/RELEASE_X86_64 x86_64
Comment 7 Rolf Bjarne Kvinge [MSFT] 2015-03-23 09:17:38 UTC
This is something we've fixed for the next major release (Xamarin.iOS 8.10) [1]

The problem is that in Xamarin.iOS 8.8 we must be notified when the retainCount of an object goes from 1 to 2 (so that we an prevent the GC from collecting the managed object). We override the native 'retain' method for exactly this purpose, but unfortunately iOS doesn't always call 'retain' (in this particular case the native UITextView init method creates a weak reference to itself, which increments the retainCount from 1 to 2, but without calling 'retain'). When subsequent "real" 'retain' calls are made, we don't do anything, and the GC ends up collecting the managed object soon after.

In Xamarin.iOS 8.10 we handle any 'retain' without regard for the actual retainCount, which means that we end up preventing the GC from collecting the managed object at any other (real) retain calls.

In any case there is a (quite ugly) workaround you can use, just add this to the FPTextView ctor:

	public FPTextView (CGRect frame) : base (frame)
		if (RetainCount == 2) {
			DangerousRelease ();
			DangerousRetain ();

This ensures Xamarin.iOS is notified of the retainCount jump from 1->2. Please remove the workaround once you update to 8.10, since there is no guarantee this will continue to work in the future.

[1] For history: the fix for bug #26532 fixes this issue also (although this issue is different).