xcode 为什么一个常量属性在Swift类中可能被初始化两次?

cgh8pdjw  于 2022-12-05  发布在  Swift
关注(0)|答案(1)|浏览(142)

我正在做的项目是Swift和Objective-C的混合体。

// ViewController.m
@interface ViewController ()

@property (nonatomic, strong) MyModel *model;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.model = [[MyModel alloc] initWithIntValue:10];
}

// MyModel.swift
fileprivate class SomeProperty {
    init() {
        print("SomeProperty init")
    }
}

class MyModel: BaseModel {
    private let property = SomeProperty()
}

// BaseModel.h
@interface BaseModel : NSObject

- (instancetype)initWithIntValue:(int)intValue;
- (instancetype)initWithIntValue:(int)intValue doubleValue:(double)doubleValue;

@end

// BaseModel.m
@implementation BaseModel

- (instancetype)initWithIntValue:(int)intValue doubleValue:(double)doubleValue {
    if (self = [super init]) {
        
    }
    return self;
}

- (instancetype)initWithIntValue:(int)intValue {
    return [self initWithIntValue:intValue doubleValue:0];
}

@end

有趣的是,我发现当MyModel示例被初始化时,SomeProperty init 将被打印两次,这意味着创建了两个SomeProperty示例。更糟糕的是,Debug Memory Graph显示有一个SomeProperty对象内存泄漏。那么,这是为什么呢?我该如何修复它呢?

pbpqsu0x

pbpqsu0x1#

重写 BaseModel.h,如下所示:

- (instancetype)initWithIntValue:(int)intValue;
- (instancetype)initWithIntValue:(int)intValue doubleValue:(double)doubleValue NS_DESIGNATED_INITIALIZER;

请注意第二个初始化函数末尾的NS_DESIGNATED_INITIALIZER标记。(您可能需要滚动我的代码才能看到它。)
这个标记,除了它在Objective-C中的作用(作为一个宏)之外,告诉Swift两个初始化器都不是指定的初始化器; Swift得出结论,第一个是方便的初始化器,这是正确的;它调用另一个初始化器,在本例中即为指定的初始化器。
如果没有NS_DESIGNATED_INITIALIZER标记,Swift会错误地解释这种情况,因为Swift初始化器和Objective-C初始化器之间的关系(已经相当复杂了)。它认为 * 两个 * 初始化器都是指定的初始化器,你会从Swift得到这种奇怪的双重初始化。

相关问题