views:

31

answers:

1

I've got a UIPickerViewModel that's supposed to fire an event when its selected value changes, but by the time Selected is called, the EventHandler is null. Code (somewhat simplified):

public class MyPickerViewModel: UIPickerViewModel {
    public event EventHandler SelectionChanged;

    public void PrintWhetherSelectionChangedIsNull() {
         System.Console.WriteLine(SelectionChanged == null ? "yes" : "no");
    }

    public override void Selected(UIPickerView picker, int row, int comp) {
        if (SelectionChanged != null) { // it always is, though
            SelectionChanged(this, new EventArgs());
        }
    }
}

public class SomeView: UIView {
    SomeView(MyPickerViewModel model) {
        model.SelectionChanged += delegate(object s, EventArgs e) { 
            DoSomething();
        }

        model.PrintWhetherSelectionChangedIsNull(); // prints "no"
    }

    private void DoSomething() { /* never called */ }
}

I'm pretty sure there's only one instance of the model, and that the EventHandler is non-null before becoming null again.

I'm guessing the delegates I've added to the EventHandler are getting garbage collected or something, but that's just a guess. Can anyone point me to a good primer on C# / iOS object lifecycles?

Update: I tried using a named EventHandler, an instance variable on the view, and the problem's still there. So it's not just a garbage collection issue.

A: 

Try updating the SomeView so it stores the model value, just to be sure, it does not release the reference for itself for some reason.

public class SomeView: UIView {

MyPickerViewModel _model;

SomeView(MyPickerViewModel model) {  
    _model = model;

    _model.SelectionChanged += delegate(object s, EventArgs e) {   
        DoSomething();  
    }  

    _model.PrintWhetherSelectionChangedIsNull(); // prints "no"  
}  

private void DoSomething() { /* should be called now */ }  

}

Pavel Sich