Skip to content

Swiftgen code crashing after return of class in method that returns NSObject #2871

@tarrinneal

Description

@tarrinneal

This swift input

class EmptyClassBridge: NSObject {}

@objc func echoObject() -> NSObject? {
        return EmptyClassBridge()
}

which ffigen makes into

  objc.NSObject? echoObject() {
    objc.checkOsVersionInternal(
      'NIHostIntegrationCoreApiSetup.echoObject',
      iOS: (false, (13, 0, 0)),
      macOS: (false, (16, 0, 0)),
    );
    final $ret = _objc_msgSend_151sglz(object$.ref.pointer, _sel_echoObject);
    return $ret.address == 0
        ? null
        : objc.NSObject.fromPointer($ret, retain: true, release: true);
  }

and

late final _class_EmptyClassBridge = objc.getClass(
  "test_plugin.EmptyClassBridge",
);
late final _sel_isKindOfClass_ = objc.registerName("isKindOfClass:");
final _objc_msgSend_19nvye5 = objc.msgSendPointer
    .cast<
      ffi.NativeFunction<
        ffi.Bool Function(
          ffi.Pointer<objc.ObjCObjectImpl>,
          ffi.Pointer<objc.ObjCSelector>,
          ffi.Pointer<objc.ObjCObjectImpl>,
        )
      >
    >()
    .asFunction<
      bool Function(
        ffi.Pointer<objc.ObjCObjectImpl>,
        ffi.Pointer<objc.ObjCSelector>,
        ffi.Pointer<objc.ObjCObjectImpl>,
      )
    >();
typedef instancetype = ffi.Pointer<objc.ObjCObjectImpl>;
typedef Dartinstancetype = objc.ObjCObject;
late final _sel_init = objc.registerName("init");
final _objc_msgSend_151sglz = objc.msgSendPointer
    .cast<
      ffi.NativeFunction<
        ffi.Pointer<objc.ObjCObjectImpl> Function(
          ffi.Pointer<objc.ObjCObjectImpl>,
          ffi.Pointer<objc.ObjCSelector>,
        )
      >
    >()
    .asFunction<
      ffi.Pointer<objc.ObjCObjectImpl> Function(
        ffi.Pointer<objc.ObjCObjectImpl>,
        ffi.Pointer<objc.ObjCSelector>,
      )
    >();
late final _sel_new = objc.registerName("new");
late final _sel_allocWithZone_ = objc.registerName("allocWithZone:");
final _objc_msgSend_1cwp428 = objc.msgSendPointer
    .cast<
      ffi.NativeFunction<
        ffi.Pointer<objc.ObjCObjectImpl> Function(
          ffi.Pointer<objc.ObjCObjectImpl>,
          ffi.Pointer<objc.ObjCSelector>,
          ffi.Pointer<objc.NSZone>,
        )
      >
    >()
    .asFunction<
      ffi.Pointer<objc.ObjCObjectImpl> Function(
        ffi.Pointer<objc.ObjCObjectImpl>,
        ffi.Pointer<objc.ObjCSelector>,
        ffi.Pointer<objc.NSZone>,
      )
    >();
late final _sel_alloc = objc.registerName("alloc");

/// Generated bridge class from Pigeon that moves data from Swift to Objective-C.
///
/// iOS: introduced 13.0.0
/// macOS: introduced 16.0.0
extension type EmptyClassBridge._(objc.ObjCObject object$)
    implements objc.ObjCObject, objc.NSObject {
  /// Constructs a [EmptyClassBridge] that points to the same underlying object as [other].
  EmptyClassBridge.as(objc.ObjCObject other) : object$ = other {
    objc.checkOsVersionInternal(
      'EmptyClassBridge',
      iOS: (false, (13, 0, 0)),
      macOS: (false, (16, 0, 0)),
    );
    assert(isA(object$));
  }

  /// Constructs a [EmptyClassBridge] that wraps the given raw object pointer.
  EmptyClassBridge.fromPointer(
    ffi.Pointer<objc.ObjCObjectImpl> other, {
    bool retain = false,
    bool release = false,
  }) : object$ = objc.ObjCObject(other, retain: retain, release: release) {
    objc.checkOsVersionInternal(
      'EmptyClassBridge',
      iOS: (false, (13, 0, 0)),
      macOS: (false, (16, 0, 0)),
    );
    assert(isA(object$));
  }

  /// Returns whether [obj] is an instance of [EmptyClassBridge].
  static bool isA(objc.ObjCObject obj) => _objc_msgSend_19nvye5(
    obj.ref.pointer,
    _sel_isKindOfClass_,
    _class_EmptyClassBridge,
  );

  /// alloc
  static EmptyClassBridge alloc() {
    final $ret = _objc_msgSend_151sglz(_class_EmptyClassBridge, _sel_alloc);
    return EmptyClassBridge.fromPointer($ret, retain: false, release: true);
  }

  /// allocWithZone:
  static EmptyClassBridge allocWithZone(ffi.Pointer<objc.NSZone> zone) {
    final $ret = _objc_msgSend_1cwp428(
      _class_EmptyClassBridge,
      _sel_allocWithZone_,
      zone,
    );
    return EmptyClassBridge.fromPointer($ret, retain: false, release: true);
  }

  /// new
  static EmptyClassBridge new$() {
    final $ret = _objc_msgSend_151sglz(_class_EmptyClassBridge, _sel_new);
    return EmptyClassBridge.fromPointer($ret, retain: false, release: true);
  }

  /// Returns a new instance of EmptyClassBridge constructed with the default `new` method.
  EmptyClassBridge() : this.as(new$().object$);
}

extension EmptyClassBridge$Methods on EmptyClassBridge {
  /// init
  EmptyClassBridge init() {
    objc.checkOsVersionInternal(
      'EmptyClassBridge.init',
      iOS: (false, (2, 0, 0)),
      macOS: (false, (10, 0, 0)),
    );
    final $ret = _objc_msgSend_151sglz(
      object$.ref.retainAndReturnPointer(),
      _sel_init,
    );
    return EmptyClassBridge.fromPointer($ret, retain: false, release: true);
  }
}

crashes after return EmptyClassBridge()

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[test_plugin.EmptyClassBridge data]: unrecognized selector sent to instance 0x600000018f60'

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions