Xamarin-macios: macOS: NSTextView.SmartInsert crashes

Created on 11 Apr 2020  路  4Comments  路  Source: xamarin/xamarin-macios

I feel like the SmartInsert method of NSTextView is not bound correctly. From what I understand, the method signature accepts a string pointer, but the C# method only accepts normal string input parameters.

NSTextView fieldEditor = ...;
fieldEditor.SmartInsert("stringToInsert", range, "", "");
bug macOS

Most helpful comment

Not needed, thanks - worked around it by using SmartInsertBefore and SmartInsertAfter methods

All 4 comments


Generated code

[Export ("smartInsertForString:replacingRange:beforeString:afterString:")]
[BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)]
public virtual void SmartInsert (string pasteString, NSRange charRangeToReplace, string beforeString, string afterString)
{
    global::AppKit.NSApplication.EnsureUIThread ();
    if (pasteString == null)
        throw new ArgumentNullException ("pasteString");
    if (beforeString == null)
        throw new ArgumentNullException ("beforeString");
    if (afterString == null)
        throw new ArgumentNullException ("afterString");
    var nspasteString = NSString.CreateNative (pasteString);
    var nsbeforeString = NSString.CreateNative (beforeString);
    var nsafterString = NSString.CreateNative (afterString);

    if (IsDirectBinding) {
        global::ObjCRuntime.Messaging.void_objc_msgSend_IntPtr_NSRange_IntPtr_IntPtr (this.Handle, selSmartInsertForString_ReplacingRange_BeforeString_AfterString_Handle, nspasteString, charRangeToReplace, nsbeforeString, nsafterString);
    } else {
        global::ObjCRuntime.Messaging.void_objc_msgSendSuper_IntPtr_NSRange_IntPtr_IntPtr (this.SuperHandle, selSmartInsertForString_ReplacingRange_BeforeString_AfterString_Handle, nspasteString, charRangeToReplace, nsbeforeString, nsafterString);
    }
    NSString.ReleaseNative (nspasteString);
    NSString.ReleaseNative (nsbeforeString);
    NSString.ReleaseNative (nsafterString);

}

It seems the binding has a few issues:

  1. beforeString and afterString are _out_ variables, so they shouldn't be passed in by the user.
  2. The binding should also expose an NSString overload to allow using NSAttributedString.

I suppose the binding method should look something like below. Not sure about exposing a to expose virtual methods for string parameters, when an NSAttributedString could be passed.

[Obsolete]
public virtual void SmartInsert (string pasteString, NSRange charRangeToReplace, string beforeString, string afterString) {}

public virtual void SmartInsert (NSString pasteString, NSRange charRangeToReplace, out NSString? beforeString, out NSString? afterString) {}

Confirmed, looks like a bad binding at first viewing.

Let me look at fixing it, @tipa do you need a manual binding to work around this?

Not needed, thanks - worked around it by using SmartInsertBefore and SmartInsertAfter methods

Was this page helpful?
0 / 5 - 0 ratings