You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 20:36:03