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

在Init中调用函数设变量,拆分ContactInfo数组遇未初始化错误

解决ContactInfo拆分数组初始化&Init调用函数的问题

嗨,我正好做过类似的个人资料模块,给你捋捋怎么搞定这两个问题:

1. 先解决数组未初始化报错的问题

Swift是强类型语言,非可选的存储属性必须在实例初始化完成前拥有确定的值,所以最省心的方式是提前给三个数组设初始值——直接初始化为空数组就行,既能避免报错,还不用后续处理可选类型的解包麻烦。

假设你的基础数据模型是这样的(可以根据实际情况调整):

// 用户基础信息模型
struct Contact {
    let userID: String
    // 其他如昵称、头像等信息...
}

// 联系方式汇总模型
struct ContactInfo {
    let phoneNumbers: [String]? // 可能是可选数组,也可能是必选
    let emails: [String]?
    let addresses: [Address]? // 地址用自定义模型存储
}

// 地址详情模型
struct Address {
    let street: String
    let city: String
    let zipCode: String
}

那三个拆分后的数组就这么定义:

// 在ViewModel或者ViewController中声明
var contactInfoPhoneList: [String] = []
var contactInfoEmailList: [String] = []
var contactInfoAddressList: [Address] = []

空数组是合法的初始值,后续再填充数据就不会有问题了。

2. 在Init里调用函数拆分数据

不管你是用ViewModel分离业务逻辑,还是直接在ViewController里处理,都可以在初始化方法里传入contact和contactInfo,然后立即调用拆分函数填充数组。

推荐用ViewModel的实现方式(更清晰的架构)

class ContactProfileViewModel {
    let contact: Contact
    var contactInfoPhoneList: [String] = []
    var contactInfoEmailList: [String] = []
    var contactInfoAddressList: [Address] = []
    
    // 初始化时直接传入两个变量,并调用解析函数
    init(contact: Contact, contactInfo: ContactInfo) {
        self.contact = contact
        self.parseContactInfo(contactInfo)
    }
    
    // 私有函数:把ContactInfo的内容拆分到三个数组中
    private func parseContactInfo(_ info: ContactInfo) {
        // 如果ContactInfo里的属性是可选类型,用空数组兜底避免nil
        contactInfoPhoneList = info.phoneNumbers ?? []
        contactInfoEmailList = info.emails ?? []
        contactInfoAddressList = info.addresses ?? []
        
        // 要是属性是必选非可选的,直接赋值即可:
        // contactInfoPhoneList = info.phoneNumbers
    }
}

直接在ViewController里处理的方式

class ContactProfileVC: UITableViewController {
    let contact: Contact
    let contactInfo: ContactInfo
    var contactInfoPhoneList: [String] = []
    var contactInfoEmailList: [String] = []
    var contactInfoAddressList: [Address] = []
    
    // 自定义初始化方法
    init(contact: Contact, contactInfo: ContactInfo) {
        self.contact = contact
        self.contactInfo = contactInfo
        super.init(style: .insetGrouped) // 选择你需要的TableView风格
        // 调用数据拆分函数
        setupContactData()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupContactData() {
        contactInfoPhoneList = contactInfo.phoneNumbers ?? []
        contactInfoEmailList = contactInfo.emails ?? []
        contactInfoAddressList = contactInfo.addresses ?? []
        // 数据准备完成后刷新TableView
        tableView.reloadData()
    }
    
    // 实现TableView数据源方法,对应三个分区展示内容
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 3 // 电话、邮箱、地址三个分区
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        switch section {
        case 0: return contactInfoPhoneList.count
        case 1: return contactInfoEmailList.count
        case 2: return contactInfoAddressList.count
        default: return 0
        }
    }
    
    // 配置Cell内容
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ContactCell", for: indexPath)
        switch indexPath.section {
        case 0:
            cell.textLabel?.text = contactInfoPhoneList[indexPath.row]
        case 1:
            cell.textLabel?.text = contactInfoEmailList[indexPath.row]
        case 2:
            let address = contactInfoAddressList[indexPath.row]
            cell.textLabel?.text = "\(address.street), \(address.city) \(address.zipCode)"
        default:
            break
        }
        return cell
    }
}

额外注意点

  • 如果ContactInfo里的属性是必选非可选类型,直接赋值即可,不用?? []兜底;
  • 若地址是更复杂的结构,确保你的Address模型初始化逻辑正确;
  • 用ViewModel的话,后续TableView的数据源可以直接绑定ViewModel里的数组,代码耦合度更低、更易维护。

内容的提问来源于stack exchange,提问作者user3628240

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:04:49