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

如何判断UIViewController是系统SDK类还是用户自定义类?

判断UIViewController是自定义类还是系统类的方案

当然有靠谱的办法实现这个需求,完全不用给现有自定义控制器加任何额外属性或方法,非常适合你的现有项目场景。下面是具体的实现思路和代码:

核心思路

系统提供的UIViewController子类(比如UITableViewController、UIAlertController这类)都属于UIKit框架的Bundle,而我们自己写的自定义控制器默认会放在项目的主Bundle里。所以通过对比类所属的Bundle标识符,就能轻松区分两者。如果需要更严谨,还可以配合系统控制器类名列表做兜底校验。

实现controllerIsUserDefined方法

基础版(适用于绝大多数场景)

这个版本利用Bundle归属判断,逻辑简洁且可靠:

@implementation Helper

+ (BOOL)controllerIsUserDefined:(NSString *)controllerName {
    // 通过类名获取对应的Class
    Class controllerClass = NSClassFromString(controllerName);
    if (!controllerClass) {
        return NO;
    }
    
    // 获取当前类所属的Bundle
    NSBundle *classBundle = [NSBundle bundleForClass:controllerClass];
    // 获取项目的主Bundle
    NSBundle *mainBundle = [NSBundle mainBundle];
    
    // 对比Bundle标识符:主Bundle里的类就是自定义类
    return [classBundle.bundleIdentifier isEqualToString:mainBundle.bundleIdentifier];
}

@end

进阶版(排除第三方库控制器)

如果你的项目里引入了第三方库的控制器,不想把它们当成自定义类处理,可以在基础版的基础上增加Bundle过滤:

@implementation Helper

+ (BOOL)controllerIsUserDefined:(NSString *)controllerName {
    Class controllerClass = NSClassFromString(controllerName);
    if (!controllerClass) {
        return NO;
    }
    
    NSBundle *classBundle = [NSBundle bundleForClass:controllerClass];
    NSBundle *mainBundle = [NSBundle mainBundle];
    
    // 仅主Bundle的类才进入下一步判断
    if (![classBundle.bundleIdentifier isEqualToString:mainBundle.bundleIdentifier]) {
        return NO;
    }
    
    // 兜底:排除可能重名的系统控制器类(不推荐自己创建和系统同名的类)
    NSSet *systemControllerNames = [NSSet setWithObjects:
                                    @"UIViewController",
                                    @"UITableViewController",
                                    @"UINavigationController",
                                    @"UITabBarController",
                                    @"UIAlertController",
                                    @"UISplitViewController",
                                    @"UIPageViewController",
                                    @"UIActivityViewController",
                                    nil];
    
    return ![systemControllerNames containsObject:controllerName];
}

@end

使用方式

就像你之前计划的那样,在方法交换后的控制器生命周期方法里调用即可:

NSString *controllerName = NSStringFromClass([self class]);
if([Helper controllerIsUserDefined:controllerName]) {
    // 仅针对用户自定义UIViewController类执行操作
}

这个方案完全不需要修改现有项目里的任何自定义控制器,直接集成就能生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:11:49