Objective-C中使用segue传值延迟首次传值为nil如何解决
问题原因
- 核心触发逻辑冲突:你大概率在Storyboard中直接将UITableViewCell和目标
OrderListViewController绑定了segue。这种情况下系统触发顺序是:先执行prepareForSegue:方法,再执行tableView:didSelectRowAtIndexPath:方法。你第一次点击时,prepareForSegue:执行时self.passStoreData还没被赋值,所以拿到的是nil;第二次点击时,self.passStoreData已经被上一次的didSelect方法赋值,所以能拿到值,本质是拿到的上一次选中的数据,只是两次点击同一行才会看起来结果正确。 - 代码逻辑小问题:你在
prepareForSegue:里把存整个店铺数据的self.passStoreData赋值给了目标VC的theStoreId属性,属性类型不匹配,如果你只需要传storeId的话应该传self.passStoreId才对。
修复方案
方案1:移除Cell绑定的segue,改用VC层面的segue
- 步骤1:打开Storyboard,删除原来从UITableViewCell拖到
OrderListViewController的segue,改为从当前页面的VC顶部黄色图标拖到目标VC,segue标识符依然设置为showOrder - 步骤2:修正
prepareForSegue:里的赋值逻辑,确保传对属性:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"showOrder"]) { OrderListViewController *orderListVc = [segue destinationViewController]; // 仅需要传storeId就用self.passStoreId,需要传整个数据就对应修改目标VC的属性名 orderListVc.theStoreId = self.passStoreId; } }
原有didSelect方法不需要修改,因为你已经在里面主动调用performSegueWithIdentifier:sender:,会保证先给属性赋值再触发segue,完全避免顺序问题。
方案2:保留Cell绑定的segue,通过sender传值
如果不想修改Storyboard的绑定,就删掉didSelect里主动触发segue的代码,直接用sender传递选中的数据:
- 步骤1:删除didSelect里的
[self performSegueWithIdentifier:@"showOrder" sender:self];代码:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSDictionary *selectStore = self.storeList[indexPath.row]; self.passStoreData = selectStore; self.passStoreId = [selectStore valueForKey:@"storeId"]; self.passStoreName = [selectStore valueForKey:@"storeName"]; NSString *store = [NSString stringWithFormat:@"%@ : %@", self.passStoreId, self.passStoreName]; [self.storeButton setTitle:store forState:UIControlStateNormal]; storeTable.hidden = YES; // 不需要主动调用performSegue,系统会通过Cell绑定的segue自动跳转 }
- 步骤2:在prepareForSegue里直接从sender获取选中数据,不需要依赖成员变量的中间存储:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"showOrder"]) { OrderListViewController *orderListVc = [segue destinationViewController]; // 拿到选中的cell对应的indexPath NSIndexPath *selectIndex = [self.tableView indexPathForCell:sender]; NSDictionary *selectStore = self.storeList[selectIndex.row]; orderListVc.theStoreId = selectStore[@"storeId"]; } }
内容的提问来源于stack exchange,提问作者Jasper Guillermo
相关产品推荐
相关产品推荐

