Используйте NSProxy в Swift 4.1
Как создать NSProxy
подкласс в Swift?
Попытка добавить любой из init
методы завершаются с ошибкой:
"Super init не может быть вызван вне инициализатора" или "Super init не вызывается на всех путях до возврата из инициализатора"
Использование подкласса Objective-C в качестве базового класса работает, но больше похоже на взлом:
// Create a base class to use instead of `NSProxy`
@interface WorkingProxyBaseClass : NSProxy
- (instancetype)init;
@end
@implementation WorkingProxyBaseClass
- (instancetype)init
{
if (self) {
}
return self;
}
@end
// Use the newly created Base class to inherit from in Swift
import Foundation
class TestProxy: WorkingProxyBaseClass {
override init() {
super.init()
}
}
2 ответа
NSProxy - это абстрактный класс. В документации Apple о NSProxy говорится: "Абстрактный суперкласс, определяющий API для объектов, которые действуют как заместители для других объектов или для объектов, которые еще не существуют".
Документы об абстрактном классе Википедии говорят:
В языке, который поддерживает наследование, абстрактный класс или абстрактный базовый класс (ABC) - это класс, который не может быть создан, потому что он либо помечен как абстрактный, либо просто определяет абстрактные методы (или виртуальные методы).
Calling super.init()
для абстрактного класса это неправильно. Во втором классе ты не звонишьsuper.init()
для абстрактного класса, но из WorkingProxyBaseClass
который является конкретным классом. В Objective c вы не звонили[super init]
следовательно, код работает.
Простое решение: создать класс Objective-C, который наследуется от NSProxy, а затем наследовать от него класс Swift.
Пример на моем GitHub: https://gist.github.com/SoundBlaster/0e53bae4ab814537c5868564d95eb553
// Objective-C Header BaseProxyForSwift.h
NS_ASSUME_NONNULL_BEGIN
NS_SWIFT_NAME(BaseProxyForSwift)
@interface BaseProxyForSwift : NSProxy
+ (id)with:(id)object;
@end
NS_ASSUME_NONNULL_END
// Objective-C Implementation BaseProxyForSwift.m
#import "BaseProxyForSwift.h"
@interface BaseProxyForSwift ()
@property (nonatomic, strong) id object;
@end
@implementation BaseProxyForSwift
+ (id)with:(id)object {
BaseProxyForSwift *res = [self alloc];
res.object = object;
return res;
}
@end
// Swift Implementation BaseSwiftProxy.swift
import Foundation
public class BaseSwiftProxy: BaseProxyForSwift {}
// Usage in Swift
let a = NSObject()
let p = BaseSwiftProxy.with(a)
Не забывайте о связующих заголовках Objective-C, если вы будете смешивать языки в одном проекте: https://developer.apple.com/documentation/swift/importing-objective-c-into-swift.