下面是swift中的一个定义:

@objc(ChartAxisBase)
open class AxisBase: ComponentBase
{
    public override init()
    {
        super.init()
    }

    /// Custom formatter that is used instead of the auto-formatter if set
    weak fileprivate var _axisValueFormatter: IAxisValueFormatter?
}

这里是valueFormatter的getter和setter:
open var valueFormatter: IAxisValueFormatter?
{
    get
    {
        if _axisValueFormatter == nil ||
            (_axisValueFormatter is DefaultAxisValueFormatter &&
                (_axisValueFormatter as! DefaultAxisValueFormatter).hasAutoDecimals &&
                (_axisValueFormatter as! DefaultAxisValueFormatter).decimals != decimals)
        {
            let df = DefaultAxisValueFormatter(decimals: decimals)
            _axisValueFormatter = df
            NSLog("found nil vf, assigning to \(_axisValueFormatter)")
        }
        NSLog("returning _axisValueFormatter: \(_axisValueFormatter)")
        return _axisValueFormatter
    }
    set
    {
        _axisValueFormatter = newValue ?? DefaultAxisValueFormatter(decimals: decimals)
    }
}

setter将检测_axisValueFormatter是否为nil,它将为它创建一个默认值并返回。
但是,稍后在objective-C文件中,我尝试将其初始化为:
-(void)viewDidLoad {
    ChartXAxis *xAxis = _chartView.xAxis;
    ChartDefaultAxisValueFormatter *f = [[ChartDefaultAxisValueFormatter alloc] initWithFormatter:leftAxisFormatter];
    xAxis.valueFormatter = [[ChartDefaultAxisValueFormatter alloc] initWithFormatter:leftAxisFormatter];
    NSLog(@"x axis vf:%@", xAxis.valueFormatter);

    ChartYAxis *leftAxis = _chartView.leftAxis;
    leftAxis.valueFormatter = [[ChartDefaultAxisValueFormatter alloc] initWithFormatter:leftAxisFormatter];
    NSLog(@"left axis vf:%@", leftAxis.valueFormatter);
}

xAxis.valueFormatterleftAxis.valueFormatter根据日志,现在为零:
2017-01-11 12:38:25.819 ChartsDemo[49440:3296871] found nil vf, assigning to Optional(<ChartDefaultAxisValueFormatter: 0x608000268480>)
2017-01-11 12:38:25.820 ChartsDemo[49440:3296871] returning nil
2017-01-11 12:38:25.820 ChartsDemo[49440:3296871] x axis vf:(null)
2017-01-11 12:38:25.821 ChartsDemo[49440:3296871] found nil vf, assigning to Optional(<ChartDefaultAxisValueFormatter: 0x608000269e80>)
2017-01-11 12:38:25.821 ChartsDemo[49440:3296871] returning nil
2017-01-11 12:38:25.821 ChartsDemo[49440:3296871] left axis vf:(null)

然而,
如果我这样改变leftAxis
ChartDefaultAxisValueFormatter *lf = [[ChartDefaultAxisValueFormatter alloc] initWithFormatter:leftAxisFormatter];
leftAxis.valueFormatter = lf;
NSLog(@"left axis vf:%@", leftAxis.valueFormatter);

左撇子现在将有一个格式化程序:
2017-01-11 12:40:26.147 ChartsDemo[49582:3311643] returning Optional(<ChartDefaultAxisValueFormatter: 0x608000265cc0>)
2017-01-11 12:40:26.147 ChartsDemo[49582:3311643] left axis vf:<ChartDefaultAxisValueFormatter: 0x608000265cc0>

我知道这不是一个好的用户案例,因为它很弱,viewDidLoad()完成后,它应该都消失了,但只要坚持日志,我现在很困惑,我不认为创建一个新的指针会有这么大的关系。我想我应该犯一个愚蠢的错误,但我现在太盲目了,看不见它。
对于任何可以提供帮助的人,请从以下网站下载整个项目:
https://github.com/liuxuan30/Charts/archive/Weak.zip
例如,可以用BarChartViewController.m中的代码替换viewDidLoad对应项。
可能需要通过Realm安装carthage bootstrap才能运行ChartsDemo。

最佳答案

在这一行上,看起来您正在构造一个新对象并将其分配给弱引用:

 _axisValueFormatter = newValue ?? DefaultAxisValueFormatter(decimals: decimals)

不能这样做,因为它的retain计数为零(弱引用不调用retain)。因此,它将立即被释放,因为当retain count变为0时,新创建的对象将被取消初始化。有人需要对这个物体保持强烈的参照。
这是不是有必要变得软弱的原因?弱通常用于中断保留周期,但我不认为您的Debug TraceValueFrimeTATER保持AxISBASE实例,因为您没有将其传递到构造函数中。
你的目标C代码也有同样的问题。初始化一个强引用并将其分配给堆栈上的变量f(retain count为1)。将f赋给弱引用(retain count仍然是1),然后f超出范围,retain count降为0,对象被释放;弱引用现在指向nil。将F提升到一个存在于类的生命中的属性,而不是VIEWDIDHOLD,它应该解决这个问题,但是我认为更好的是摆脱弱的整体,除非你有一个令人信服的用途。

10-08 12:30