Bug 7742 - UINavigationController not working in iOS 4.3 simulator
Summary: UINavigationController not working in iOS 4.3 simulator
Status: RESOLVED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: XI runtime ()
Version: 6.0.x
Hardware: PC Windows
: --- normal
Target Milestone: Untriaged
Assignee: Sebastien Pouliot
URL:
: 7788 8235 ()
Depends on:
Blocks:
 
Reported: 2012-10-09 11:08 UTC by Nikita Kareev
Modified: 2012-11-05 22:14 UTC (History)
6 users (show)

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


Attachments
fix candidate (4.06 MB, application/octet-stream)
2012-10-09 21:40 UTC, Sebastien Pouliot
Details


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:
Status:
RESOLVED FIXED

Description Nikita Kareev 2012-10-09 11:08:06 UTC
For some reason UINavigationController doesn't work in iOS 4.3 simulator with latest MonoTouch (6.0.4) and XCode. Initialising it with UIViewController or pushing UIViewController in it produces the following error:

MonoTouch.Foundation.MonoTouchException: Objective-C exception thrown.  Name: NSInvalidArgumentException Reason: -[NSConcreteHashTable objectAtIndex:]: unrecognized selector sent to instance 0xb6a6fb0
  at (wrapper managed-to-native) MonoTouch.ObjCRuntime.Messaging:IntPtr_objc_msgSend_UInt32 (intptr,intptr,uint)
  at MonoTouch.Foundation.NSArray.ArrayFromHandle[UIViewController] (IntPtr handle) [0x0002d] in /Developer/MonoTouch/Source/monotouch/src/shared/Foundation/NSArray.cs:170
  at MonoTouch.UIKit.UIViewController.get_ChildViewControllers () [0x00010] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIViewController.g.cs:1744
  at MonoTouch.UIKit.UINavigationController.get_ViewControllers () [0x00052] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UINavigationController.g.cs:325
  at MonoTouch.UIKit.UINavigationController.PushViewController (MonoTouch.UIKit.UIViewController viewController, Boolean animated) [0x00054] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UINavigationController.g.cs:179

This error doesn't occur with 5.0 and 6.0 simulators. I'm building it with SDK version 4.3, because cannot find another way to launch app in iOS 4.3 simulator.
Comment 1 Sebastien Pouliot 2012-10-09 13:21:56 UTC
The `childViewControllers` was introduced in iOS 5.0, but it's getting called (indirectly by the UINavigationController.ViewControllers property) to keep the backing fields in sync. This cause problem if executed in 4.3. 

I'll look into this, i.e. how we can support both scenarios...
Comment 2 Sebastien Pouliot 2012-10-09 21:40:09 UTC
Created attachment 2724 [details]
fix candidate

To use the attached assembly (on top of MonoTouch 6.0.4) do:

1) backup your /Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll and /Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll.mdb files

2) copy the attached file to /Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll

3) remove the /Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll.mdb symbols (they won't match anymore)

4) clean, rebuild and test your application
Comment 3 Sebastien Pouliot 2012-10-09 21:41:42 UTC
Could you try the attached hot fix to see if this solve your issue ?

I'll look if the same condition occurs for other cases and, if the solution works, apply it for future versions of MonoTouch.
Comment 4 Nikita Kareev 2012-10-10 02:03:38 UTC
This patch fixes a problem with UINavigationController. But there are more of them with iOS 4.3, unfortunately. UIViewController.DismissViewController also throws exception, but deprecated UIViewController.DismissModalViewControllerAnimated works fine. But this can be solved with iOS version check.
Comment 5 Nikita Kareev 2012-10-10 02:29:47 UTC
Also deprecated PresentModalViewController works, but PresentViewController does not.
Comment 6 Sebastien Pouliot 2012-10-10 08:40:15 UTC
Comment #4 and #5 are both normal (and unrelated to the original issue).

#4: UIViewController.DismissViewController was _added_ in iOS 5.0 so it won't work on iOS 4.3. DismissModalViewControllerAnimated exist since iOS 2.0, so it will be available in 4.3.

#5: PresentViewController was _added_ in iOS 5.0 so it won't work on iOS 4.3, while PresentModalViewController exist since iOS 2.0 (and will work in 4.3).
Comment 7 Sebastien Pouliot 2012-10-11 12:24:42 UTC
*** Bug 7788 has been marked as a duplicate of this bug. ***
Comment 8 Sebastien Pouliot 2012-10-11 15:20:57 UTC
Fixed in
ios6: d82b4cecb2c6b4db15339f141bef919b83633c93
master: 598c450ebf8dc6a4e1511d86db5ed7a67cd927a5
Comment 9 Chris Hatton 2012-10-16 13:36:45 UTC
We are also affected by this issue as we need to support 4.3.x devices for our client.

I can confirm it affects device and not just simulator.

The hot-fix works but I hope for a stable release soon because it doesn't feel great going to production with a patched runtime, which we will be forced to do.
Comment 12 Sebastien Pouliot 2012-10-17 08:12:05 UTC
6.0.5 is being tested and will be available in the 'beta' channel once it's cleared by QA (and a few days later will be, if nothing else is reported, promoted to stable).

In the mean time you can use the attached hotfix. It's a different fix but it does the same thing (avoiding a call on older iOS versions). The final fix main difference is that it ensure this will be done automatically based on the [Since] attributes in the future (but in 6.0.x ViewControllers was the only case).
Comment 13 Chris Hatton 2012-10-17 08:16:34 UTC
In mean time we have already applied our own source code fix
on top of the 6.0.4 stable release, by extending all UINavigationControllers
with:

public class PatchedNavigationController : UINavigationController
    {
        public PatchedNavigationController(UIViewController rootViewController)
: base(rootViewController) {}

        private static Selector vcSelector = new Selector("viewControllers");

        private UIViewController[] __mt_ViewControllers_var;

        public override UIViewController[] ViewControllers
        {
            [Export ("viewControllers", ArgumentSemantic.Copy)]
            get
            {
                if(UIDevice.CurrentDevice.CheckSystemVersion(5,0))
                {
                    return base.ViewControllers;
                }
                else
                {
                    UIApplication.EnsureUIThread ();
                    UIViewController[] array;
                    if (this.IsDirectBinding)
                    {
                        array = NSArray.ArrayFromHandle<UIViewController>
(Messaging.IntPtr_objc_msgSend (base.Handle, vcSelector.Handle));
                    }
                    else
                    {
                        array = NSArray.ArrayFromHandle<UIViewController>
(Messaging.IntPtr_objc_msgSendSuper (base.SuperHandle, vcSelector.Handle));
                    }
                    if (!NSObject.IsNewRefcountEnabled ())
                    {
                        this.__mt_ViewControllers_var = array;
                    }

                    return array;
                }
            }
            [Export ("setViewControllers:", ArgumentSemantic.Copy)]
            set
            {
                base.ViewControllers = value;
            }
        }
    }

This bypasses a call to ChildViewControllers which looks like it was only
called for initialisation side effects, but caused the crash during
enumeration.
Comment 14 Sebastien Pouliot 2012-11-05 22:14:33 UTC
*** Bug 8235 has been marked as a duplicate of this bug. ***