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

搜索筛选器ViewController间数组数据传递咨询:能否用类C++指针?

嘿,这个问题在iOS开发里太常见了,我来给你好好梳理下~

关于iOS视图控制器间数组同步与回传的解决方案

一、能不能用类似C++的指针机制实现同步修改?

你想要的「无需复制数据、修改同步」是可以实现的,但不是用C++那种直接操作指针的语法,而是利用iOS语言的引用类型特性:

  • 如果用的是Objective-C:直接传递NSMutableArray实例就行!因为NSMutableArray是引用类型,两个视图控制器持有同一个对象的引用,第二个VC修改数组时,第一个VC的数组会同步变化,效果和C++指针共享内存完全一致,根本不需要复制数据。
  • 如果用的是Swift:Array是值类型(默认是写时复制,修改时会生成独立副本),直接传数组达不到同步效果。但你可以用自定义的引用类型包装类包裹数组,让两个VC持有同一个包装类实例的引用:
// 定义一个通用的数组包装类
class SharedArray<T> {
    var elements: [T]
    init(elements: [T]) {
        self.elements = elements
    }
}

// 第一个VC中创建实例并传递给第二个VC
class MainVC: UIViewController {
    let sharedData = SharedArray(elements: ["a", "b", "c"])
    
    func pushFilterVC() {
        let filterVC = FilterVC()
        filterVC.sharedArray = sharedData
        navigationController?.pushViewController(filterVC, animated: true)
    }
}

// 第二个VC中修改数组,第一个VC会同步看到变化
class FilterVC: UIViewController {
    var sharedArray: SharedArray<String>?
    
    func updateArray() {
        sharedArray?.elements.append("d")
        // 此时MainVC的sharedData.elements也会包含"d"
    }
}

二、如果不想用共享引用,怎么回传修改后的数组?

要是你担心共享引用带来的状态混乱(比如多个VC同时修改数组出问题),可以用以下几种成熟的回传方案:

1. 代理模式(最经典的iOS标准方案)

通过定义协议让第一个VC监听第二个VC的修改结果,耦合度低、代码清晰:

// 第二个VC定义代理协议
protocol FilterVCDelegate: AnyObject {
    func filterVC(_ vc: FilterVC, didFinishFiltering array: [String])
}

class FilterVC: UIViewController {
    weak var delegate: FilterVCDelegate?
    var currentArray: [String] = []
    
    // 用户完成筛选后调用
    func finishFilter() {
        delegate?.filterVC(self, didFinishFiltering: currentArray)
        dismiss(animated: true)
    }
}

// 第一个VC遵守协议并接收数据
class MainVC: UIViewController, FilterVCDelegate {
    var originalArray: [String] = []
    
    func presentFilterVC() {
        let filterVC = FilterVC()
        filterVC.delegate = self
        filterVC.currentArray = originalArray
        present(filterVC, animated: true)
    }
    
    // 实现代理方法接收修改后的数组
    func filterVC(_ vc: FilterVC, didFinishFiltering array: [String]) {
        originalArray = array
        // 这里更新UI或处理业务逻辑
    }
}

2. 闭包(简洁轻量的方案)

适合简单的回传场景,代码比代理更紧凑:

class FilterVC: UIViewController {
    var onFilterCompleted: (([String]) -> Void)?
    var currentArray: [String] = []
    
    func finishFilter() {
        onFilterCompleted?(currentArray)
        dismiss(animated: true)
    }
}

class MainVC: UIViewController {
    var originalArray: [String] = []
    
    func presentFilterVC() {
        let filterVC = FilterVC()
        filterVC.currentArray = originalArray
        // 用闭包接收回传数据
        filterVC.onFilterCompleted = { [weak self] updatedArray in
            guard let self = self else { return }
            self.originalArray = updatedArray
            // 更新UI
        }
        present(filterVC, animated: true)
    }
}

3. Combine框架(iOS 13+响应式方案)

如果你的项目用了响应式开发,可以用Combine的Publisher传递数据:

import Combine

class FilterVC: UIViewController {
    let filterResultPublisher = PassthroughSubject<[String], Never>()
    var currentArray: [String] = []
    
    func finishFilter() {
        filterResultPublisher.send(currentArray)
        dismiss(animated: true)
    }
}

class MainVC: UIViewController {
    var originalArray: [String] = []
    private var cancellables = Set<AnyCancellable>()
    
    func presentFilterVC() {
        let filterVC = FilterVC()
        filterVC.currentArray = originalArray
        filterVC.filterResultPublisher
            .receive(on: DispatchQueue.main)
            .sink(receiveValue: { [weak self] updatedArray in
                self?.originalArray = updatedArray
                // 更新UI
            })
            .store(in: &cancellables)
        present(filterVC, animated: true)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:34:57