-
Notifications
You must be signed in to change notification settings - Fork 559
Description
Ref: last part of dotnet/runtime#86649 (comment)
When instantiating a managed NSObject instance (or subclass) for an existing Objective-C object
Say we have the following managed class:
class MyObject : NSObject {
[Export ("doSomething:")]
public static void DoSomething (NSString something) {}
}
class NSString : NSObject {
protected NSString (IntPtr handle) : base (handle) {}
}In this case we do something like:
partial class MyObject {
class __RegistrarHelper_ {
[UnmanagedCallersOnly ("__MyObject_DoSomething__")]
static void DoSomething (IntPtr handle, IntPtr selector, IntPtr arg1)
{
// Runtime.GetNSObject:
// https://github.com/xamarin/xamarin-macios/blob/3dd412daa6b5522029014b0be298f27d751c5f45/src/ObjCRuntime/Runtime.cs#L1516-L1519
// basically something like this:
// if we already have a managed instance for the handle 'handle', return that
// otherwise find the constructor that takes an IntPtr (using reflection), and call that constructor
var arg1Obj = Runtime.GetNSObject ();
MyObject.DoSomething (arg1Obj);
}
}
}This is in some ways very similar to Filip's INativeObject/Selector case from above, except a bit more complex, because Runtime.GetNSObject will look up the actual runtime type of the Objective-C handle, find the closest matching C# type, and create an instance of that type. This might very well be a subclass of the type the caller expects (and this is why we can't just do a new NSString (handle) in the generated code).
Potential solution: we already generate a table to map Objective-C class -> managed type (which we use to find the closest matching C# type for a given Objective-C classr), we could add the token for the IntPtr ctor to table, so that when we find a managed type, we'll find the ctor to call too (or maybe even generate code to call the ctor directly, because calling a method given a token in C# is rather obnoxious)