2

次のコードを考えると、各要素をクリックすると問題が発生します。5 つの演習があり、foreach() ループで 5 つの要素を作成すると仮定すると、テーブルがレンダリングされ、任意の要素をクリックすると、デリゲートは常に 5 番目 (最後) の要素の演習を取得します。

要素は適切に表示され、それぞれに関連付けられた演習の名前が表示されます。期待どおりに機能しないのはデリゲートだけです。

foreach ループを使用せず、代わりに各要素をハードコードすると、期待どおりに機能します。ただし、dialogViewController を動的に設定できず、それぞれに要素タップ イベントを使用できない場合は、良くありません。

private void CreateExerciseTable()
{
Section section = new Section();

foreach (var exercise in exercises)
{
    var element = new StyledStringElement(exercise.ExerciseName, 
        delegate { AddExercise(exercise); }) 
        {
            Font = Fonts.H3,
            TextColor = UIColor.White,
            BackgroundColor = RGBColors.LightBlue,
            Accessory = UITableViewCellAccessory.DisclosureIndicator
        };

    section.Elements.Add(element);
}

var root = new RootElement("Selection") {
    section
};

 var dv = new DialogViewController(root, true);
dv.Style = UITableViewStyle.Plain;

//Remove the extra blank table lines from the bottom of the table.
UIView footer = new UIView(new System.Drawing.RectangleF(0,0,0,0));
dv.TableView.TableFooterView = footer;

dv.TableView.SeparatorColor = UIColor.White;
dv.TableView.BackgroundColor = UIColor.White;
tableFitnessExercises.AddSubview(dv.View);      
}

private void AddExercise(FitnessExercise exercise)
{
NavigationManager.FitnessRoutine.Add(exercise);
PerformSegue(UIIdentifierConstants.SegAddExerciseToFitnessRoutine, this);
}
4

1 に答える 1

8

これは古典的な閉鎖バグです!

問題は、ループ参照にアクセスしていることです。

試す:

foreach (var exercise in exercises)
{
    var localRef = exercise;
    var element = new StyledStringElement(exercise.ExerciseName, 
        delegate { AddExercise(localRef); }) 
        {
            Font = Fonts.H3,
            TextColor = UIColor.White,
            BackgroundColor = RGBColors.LightBlue,
            Accessory = UITableViewCellAccessory.DisclosureIndicator
        };

    section.Elements.Add(element);
}

詳細については、http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspxを参照してください。

于 2012-10-29T22:41:01.387 に答える