所以这是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);
}
根据log:, xAxis.valueFormatter
和leftAxis.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);
leftAxis现在将有一个格式化程序:
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。
答案 0 :(得分:0)
在这一行上,您看起来正在构建一个新对象并将其分配给弱引用:
_axisValueFormatter = newValue ?? DefaultAxisValueFormatter(decimals: decimals)
你不能这样做,因为它的保留计数为零(弱引用不会调用retain)。因此它将立即释放,因为当您的保留计数变为0并且您新创建的对象被取消初始化时会发生什么。有人需要对该对象保持强烈的引用。
这有什么理由需要弱吗?弱通常用于打破保留周期,但我不认为您的DefaultAxisValueFormatter保留了AxisBase实例,因为您没有将它传递给构造函数。
您的目标C代码存在同样的问题。初始化一个强引用并将其分配给堆栈中的变量f(保留计数为1)。您将f指定给弱引用(保留计数仍为1),然后f超出范围,保留计数降为0并且对象被取消分配;你的弱参考现在指向零。提升f为一个属于该类生命的属性,而不仅仅是viewDidLoad,它应该解决问题,但我认为除非你有一个令人信服的用途,否则最好完全摆脱弱点。