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

Objective-C中如何根据调用的ViewController为同一类传入不同数据

如何让自定义GaugeView支持多模块不同数据源?

首先得解决你遇到的两个核心问题:重复符号编译错误和GaugeView的数据源复用性,咱们一步步来:

1. 先解决重复符号的问题

你复制GaugeView类导致的duplicate symbols错误,本质是同一个类被多次编译进不同模块了。正确的做法是把GaugeView做成公共可复用组件:

  • 把GaugeView的.h和.m文件移到项目里所有模块都能访问的位置,比如创建一个Shared文件夹(在Xcode里用Group管理),或者打包成一个静态/动态Framework,让需要的模块直接引用这个公共文件,而不是复制粘贴。这样就不会出现重复定义的问题了。

2. 重构GaugeView,让它脱离固定数据源依赖

你原来的思路是在GaugeView里判断当前是哪个ViewController,这种方式会让GaugeView和ViewController强耦合,以后新增页面还要修改GaugeView的代码,非常不灵活。更好的做法是让GaugeView接收外部传入的数据,而不是自己去UserDefaults里取固定值。

具体实现步骤:

第一步:给GaugeView添加可配置的属性

在GaugeView.h里声明两个属性,用来接收外部传入的当前分数和最高分数:

@interface GaugeView : UIView
// 新增两个属性,让外部传入数据
@property (nonatomic, assign) double currentPoints;
@property (nonatomic, assign) double maxPoints;
@end

第二步:修改drawRect方法,使用属性计算比例

把原来从UserDefaults取数的逻辑删掉,直接用实例属性计算,还要加个除以0的兜底(避免maxPoints为0时崩溃):

- (void) drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    if(ctx == nil) return;
    
    // 用外部传入的属性计算,不再依赖固定的UserDefaults键
    if (self.maxPoints <= 0) {
        orangeSegmentValue = 0; // 兜底处理,防止除以0
    } else {
        orangeSegmentValue = (self.currentPoints/self.maxPoints)*270.00;
    }
    
    [self drawBackground:rect context:ctx];
}

第三步:添加属性监听,自动重绘仪表盘(优化项)

如果希望修改分数时仪表盘自动更新,可以给属性添加setter方法,触发重绘:

@implementation GaugeView

- (void)setCurrentPoints:(double)currentPoints {
    _currentPoints = currentPoints;
    [self setNeedsDisplay]; // 修改后自动重绘
}

- (void)setMaxPoints:(double)maxPoints {
    _maxPoints = maxPoints;
    [self setNeedsDisplay]; // 修改后自动重绘
}

// 原来的drawRect和其他方法...

@end

3. 在各个ViewController里使用GaugeView

现在你可以在任何模块的ViewController里,根据自己的数据源给GaugeView赋值:

比如在ViewController A里(用自己的数据源):

// 初始化GaugeView
GaugeView *gaugeView = [[GaugeView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];
// 传入当前页面的自定义数据
gaugeView.currentPoints = 85;
gaugeView.maxPoints = 150;
[self.view addSubview:gaugeView];

在原来的ViewController里(继续用UserDefaults的数据):

GaugeView *gaugeView = [[GaugeView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];
// 从UserDefaults取原来的数值,赋值给GaugeView
double maxPoints = [[NSUserDefaults standardUserDefaults] integerForKey:MAX_POINTS];
double currentPoints = [[NSUserDefaults standardUserDefaults] integerForKey:CURRENT_POINTS];
gaugeView.currentPoints = currentPoints;
gaugeView.maxPoints = maxPoints;
[self.view addSubview:gaugeView];

这样改造后,GaugeView就变成了一个通用的组件,不管哪个模块、哪个ViewController用它,都可以传入对应的数据源,完全解耦了原来的固定依赖,也解决了重复符号的问题。

内容的提问来源于stack exchange,提问作者Fabrizio L.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 02:32:35