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

能否传递对象类型给函数?泛型简化视图控制器数组类型检测方案

当然可以用泛型简化这类类型检查代码!

我之前也踩过重复写检查逻辑的坑——手里一堆不同类型的VC数组,每次检查是否包含某类VC都要写一遍contains { $0 is XXXViewController },重复代码多到头疼,泛型正好能完美解决这个问题。

第一步:写一个基础的泛型检查函数

先从最直接的泛型函数开始,它能接收VC数组和你要检查的类型,返回是否包含该类型的元素:

import UIKit

func containsViewController<T>(in array: [UIViewController], ofType type: T.Type) -> Bool {
    return array.contains { $0 is T }
}

调用的时候直接传数组和VC类型的.self就行:

let myVCs: [UIViewController] = [HomeVC(), SettingsVC(), ProfileVC()]
let hasSettingsVC = containsViewController(in: myVCs, ofType: SettingsVC.self)

第二步:用扩展让代码更优雅

上面的函数已经能用,但我们可以给[UIViewController]写个扩展,让调用方式更自然,就像数组自带的方法一样:

extension Array where Element == UIViewController {
    // 检查是否包含某类VC
    func contains<T>(type: T.Type) -> Bool {
        return contains { $0 is T }
    }
    
    // 顺便加个实用的:获取第一个该类型的VC(自动强转类型)
    func first<T>(ofType type: T.Type) -> T? {
        return first { $0 is T } as? T
    }
}

现在调用起来就清爽多了:

// 检查是否存在SettingsVC
if myVCs.contains(type: SettingsVC.self) {
    print("找到了设置页面!")
}

// 获取第一个ProfileVC并直接使用
if let profileVC = myVCs.first(ofType: ProfileVC.self) {
    profileVC.loadUserInfo() // 这里不用再手动强转,直接是ProfileVC类型
}

额外说明:严格匹配类型 vs 包含子类

上面的代码用$0 is T会匹配该类型及其子类的VC。如果你的需求是严格匹配类型(不包含子类),只需要把判断条件改成:

func containsExact<T>(type: T.Type) -> Bool {
    return contains { type(of: $0) == T.self }
}

这样一来,所有类型检查的逻辑都被复用起来,不用再重复写闭包,代码简洁性和可读性都提升了不少~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:34:39