Circular reference using picker

Former Member
Former Member
I'm implementing amenu in my application and asking user to enter/modify value.

class MainMenu extends Toybox.Lang.Object {
...
function start() {
...
Ui.pushView(new NumberChooser(...), new NumberChooserDelegate( method( :updateAttnValue ), null ), Ui.SLIDE_IMMEDIATE);
...
}

function updateAttnValue(values) {
// do something with values from picker
}

...
}

class NumberChooserDelegate extends Ui.PickerDelegate {
var acceptCB = null;
var cancelCB = null;

function initialize(accCb, cncCb) {
acceptCB = accCb;
cancelCB = cncCb;
}

function onCancel() {
if (cancelCB != null) {
cancelCB.invoke();
}
Ui.popView(Ui.SLIDE_IMMEDIATE);
}

function onAccept(values) {
if (acceptCB != null) {
acceptCB.invoke(values);
}
Ui.popView(Ui.SLIDE_IMMEDIATE);
}
}



This works fine in simulator, but I'm getting constant "Circular reference" errors in CIQ_LOG.txt on ForeRunner 230.
Problem seems to appear only after invocation of callback method meaning if I start picker and exit via Back key, then I don't get such errors after application finishes.
Please, someone, shed the light on this one.
Thanks in advance.
  • I don't see a cycle, but NumberChooserDelegate does keep an indirect reference to MainMenu via the Method object you pass to NumberChooserDelegate.initialize(). If the cycle relates to these, you _may_ be able to avoid the problem by setting both of the callbacks (acceptCB and cancelCB) to null in each of your handlers.

    function onCancel() {
    if (cancelCB != null) {
    cancelCB.invoke();
    }

    acceptCB = null;
    cancelCB = null;

    Ui.popView(Ui.SLIDE_IMMEDIATE);
    }
  • Former Member
    Former Member
    Thank you for the advice, Travis, but that didn't help, still getting circular dependency on app exit.

    Meanwhile I tried different varians including
    function onAccept(values) {
    if (acceptCB != null) {
    acceptCB.invoke(values.weak());
    }
    Ui.popView(Ui.SLIDE_IMMEDIATE);
    }

    Also I tried popping picker at much later time after I actually used values array to get total value, which could work considering ProgGuide remark that memory is freed when there are no more counters left referring to symbol.

    Not that this hinders my app anyhow (I even completed hour long run after modying values with picker without any issues), but just looks unpretty 8((
    The only difference in running app with and without issue is in app completion time: when there is no such error, then app closes in a second, if there is an issue - app closes for about 3-4 seconds and adds information to error log.
  • Former Member
    Former Member
    Accidentally I managed to find the source of this problem by analysing memory states before and after using picker. Problem appears when one or more items of picker pattern are Drawable.
    class DatePicker extends Ui.Picker {

    function initialize() {
    var months = [Rez.Strings.month01, Rez.Strings.month02, Rez.Strings.month03,
    Rez.Strings.month04, Rez.Strings.month05, Rez.Strings.month06,
    Rez.Strings.month07, Rez.Strings.month08, Rez.Strings.month09,
    Rez.Strings.month10, Rez.Strings.month11, Rez.Strings.month12];
    var title = new Ui.Text({:text=>Rez.Strings.datePickerTitle, :locX =>Ui.LAYOUT_HALIGN_CENTER, :locY=>Ui.LAYOUT_VALIGN_BOTTOM, :color=>Gfx.COLOR_WHITE});
    var separator = new Ui.Text({:text=>Rez.Strings.dateSeparator, :locX =>Ui.LAYOUT_HALIGN_CENTER, :locY=>Ui.LAYOUT_VALIGN_CENTER, :color=>Gfx.COLOR_WHITE});
    Picker.initialize({:title=>title, :pattern=>[new WordFactory(months), separator, new NumberFactory(1,31,1), separator, new NumberFactory(15,18,1,{:font=>Gfx.FONT_NUMBER_MEDIUM})]});
    }

    function onUpdate(dc) {
    dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_BLACK);
    dc.clear();
    Picker.onUpdate(dc);
    }
    }

    In this standard SDK example Ui.Text drawable "separator" is created to make neigboring pickers more readable. If I start this example (Pickers), select "Time" in pickers list and just click through it for a several times, then I may notice small memory leak, in memory view of simulator several ":" objects are visible meaning that drawables are not freed after picker view is popped.

    In my own app if I exclude Ui.Text (also used to initialize picker pattern as a separator) then I don't get circular dependency any more.

    So, the actual problem is: memory is not freed for drawables used in Ui.Picker pattern. Can be reproduced in simulator using standard Pickers sample.
    Seems like this is a SDK bug and needs to be reported to Garmin team.
  • Thanks for looking into this and reporting your findings! We'll get this investigated.
  • Thank you for finding this, it's been driving me nuts.
  • What is the status of issue? Seems I have the same problem (drawables with Picker).
  • Thanks for looking into this and reporting your findings! We'll get this investigated.


    Garmin Team, what it the status of bug? Because I also have such problems (memory wasn't released after using any pickers with drawables).
    Connect IQ SDK 1.2.11
  • Apologies for the delay! This issue feel through the cracks, but I ran across it and I was easily able to reproduce it. It has been reported for investigation.