Closed Kiwijane3 closed 4 years ago
This typically happens when you get memory management wrong. While Swift uses automatic reference counting (ARC), glib/gtk you need to unref the objects you no longer need, but only if you are the owner.
This is why there is a Protocol and two Swift types for each glib/gtk type. The classes (e.g. Widget
) use ARC while the structs (e.g. WidgetRef
) don't, i.e., the latter are simple wrappers around the underlying glib/gtk pointers (that you need to do the memory management for).
I'm happy to have a look at an example once you have one.
`import Gtk
let status = Application.run { app in let window = ApplicationWindowRef(application: app) window.title = "Hello, world" let test = Dialog(firstText: "", secondText: ""); window.setDefaultSize(width: 320, height: 240) let label = Label(str: "Hello, SwiftGtk") window.add(widget: label) window.showAll() }
guard let status = status else { fatalError("Could not create Application") } guard status == 0 else { fatalError("Application exited with status (status)") } `
That causes the fault. It only happens for dialogs in particular; Windows don't do it.
The stack trace indicates this occurs during the gtk_widget_dispose function.
I think it might be something to do with the initialisers for the varargs constructors. The issue doesn't occur if just use Dialog().
This code seems to work: `import Gtk import GtkCHelpers
let status = Application.run { app in let window = ApplicationWindowRef(application: app) window.title = "Hello, world" let dialogPointer = gtk_c_helper_dialog_new_with_button("", window.ptr.assumingMemoryBound(to: GtkWindow.self), GTK_DIALOG_MODAL, "", GTK_RESPONSE_OK); let dialog = Dialog(retainingCPointer: dialogPointer!); window.setDefaultSize(width: 320, height: 240) let label = Label(str: "Hello, SwiftGtk") window.add(widget: label) window.showAll() }
guard let status = status else { fatalError("Could not create Application") } guard status == 0 else { fatalError("Application exited with status (status)") } `
So I think the issue is that the Dialog constructors aren't using the retaining constructors, which is causing issues. I'll write a patch and make a pull request.
I've implemented a fix and made a pull request to resolve this issue.
Yes, it looks like there is a refSink() that's missing. I'll have a look.
Until this is fixed, you can work around this by using:
let test = Dialog(title: "Title", firstText: "", secondText: "")
if test.isFloating { test.refSink() }
// ...
[Edit:] No it looks like this indeed needs a ref()
not a refSink()
Thanks!
I've encountered an issue where instances of the dialog class cause a EXC_BAD_ACCESS error during their deinit function. Specifically, this issue appears to be caused during the invocation of g_object_unref in the deinit of the Object class; The code is EXC_I386_GPFLT. I suspect the issue is caused by a pointer corruption at some point. I can't provide an example at this point, since the application I'm developing is proprietary. I'll try to build one I can release as soon as possible.