MVXCommand绑定按钮点击崩溃求助:无法识别选择器异常
这个崩溃的核心原因很明确:系统尝试调用SchoolSelectionView实例上一个名为UIButton4156_TouchUpInside:的方法,但这个方法根本不存在。结合你的代码和MvvmCross的使用场景,问题出在按钮的事件绑定冲突上,下面是具体的排查和解决步骤:
1. 移除Storyboard/XIB中按钮的手动事件绑定
这是触发该崩溃最常见的原因:你在界面文件(Storyboard/XIB)里给btnEnter按钮手动添加了TouchUpInside事件绑定,但没有实现对应的方法,或者后来改用MvvmCross的Command绑定后,旧的手动绑定没有删除。
操作步骤:
- 打开
SchoolSelectionView对应的Storyboard/XIB文件 - 选中
btnEnter按钮 - 打开右侧的Connections Inspector(箭头图标)
- 在Sent Events区域,检查是否有
Touch Up Inside的绑定指向了SchoolSelectionView的某个方法(比如自动生成的UIButton4156_TouchUpInside:) - 如果有,点击绑定后的
x按钮删除它
MvvmCross的Command绑定会自动接管按钮的点击事件,旧的手动绑定会导致系统错误地尝试调用View上不存在的方法,直接引发崩溃。
2. 优化ViewModel的Command逻辑
你的ViewModel代码存在命名不一致的小问题(_loginCommand对应SchoolEnterCommand属性),虽然不会直接导致崩溃,但建议修正以避免混淆:
private IMvxCommand _schoolEnterCommand; public virtual IMvxCommand SchoolEnterCommand { get { _schoolEnterCommand = _schoolEnterCommand ?? new MvxCommand(CheckSchoolCode); return _schoolEnterCommand; } }
另外,CheckSchoolCode使用async void的写法在MvxCommand中虽然允许,但async void的异常无法被MvvmCross的全局异常处理捕获,建议改用MvxAsyncCommand和async Task,同时修正Result调用可能导致的死锁问题:
private IMvxAsyncCommand _schoolEnterCommand; public virtual IMvxAsyncCommand SchoolEnterCommand { get { _schoolEnterCommand = _schoolEnterCommand ?? new MvxAsyncCommand(CheckSchoolCode); return _schoolEnterCommand; } } private async Task CheckSchoolCode() { // 用await替代.Result,避免异步死锁 var response = await _schoolService.GetSchoolDetails(SchoolCode); if (response != null) { await _navigationService.Navigate<LoginViewModel, SchoolModel>(response); } else { Mvx.Resolve<IUserDialogs>().Alert("Invalid login credentials", "Error", "Done"); } }
3. 确认View的绑定时机
确保你的绑定代码在View的生命周期方法中执行,比如iOS的ViewDidLoad或者Android的OnCreate:
public override void ViewDidLoad() { base.ViewDidLoad(); var set = this.CreateBindingSet<SchoolSelectionView, SchoolSelectionViewModel>(); set.Bind(txtSchoolCode).To(vm => vm.SchoolCode); set.Bind(btnEnter).To(vm => vm.SchoolEnterCommand); set.Apply(); }
这样能保证绑定在View初始化完成后执行,Command可以正确关联到按钮的点击事件。
按照以上步骤排查后,应该就能解决这个崩溃问题了。
内容的提问来源于stack exchange,提问作者pankaj

