搜索筛选器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
相关产品推荐
相关产品推荐

