ios - 如何在 Swift 中翻译 @synthesize 协议变量?
问题描述
我必须将一些文件从 Objective-C 转换为 Swift。问题是我真的对被称为相同的协议和类以及我不知道如何初始化或如何转换为 Swift 的 @synthetize 协议变量感到困惑。我将尝试制定一个简单的方案。
// Protocols.h
ProtocolA {
- functionA
}
ProtocolB {
- variableNameB : ProtocolA // Can a variable be of type protocol? shouldn't it be of type class and that class is the one that follows the protocol?
- functionB
}
------------------------
// Class1.m
Class1: ProtocolB {
// This is what I don't understand at all, how is initiating itself? There are not initialisers for Protocols.
@synthesize variableNameB = _variableNameB
}
我得到的错误
如果我尝试只写var variableNameB: ProtocolA
而不给出任何值,我将在 Class1 的 init 方法中得到它:
属性“self.variableNameB”未在隐式生成的 super.init 调用中初始化
如果我尝试在 Class1 init 中初始化它,self.variableNameB = ProtocolA()
我会得到:
无法构造 ProtocolA,因为它没有可访问的初始值设定项
如果我尝试使 variableNameB 可选,所以我不会强制初始化它,我得到:
'variableNameB'的getter提供的Objective-C方法'variableNameB'与协议ProtocolB中'variableNameB'的可选要求getter冲突
由 setter 为 variableNameB 提供的 Objective-C 方法“setVariableNameB:”与协议 ProtocolB 中“variableNameB”的可选要求 setter 冲突
额外上下文、OBJECTIVE-C 和 SWIFT 的所有文件
条款和条件Reader.h
@class UserAccountManager;
@class TermsAndConditionsManager;
@protocol TermsAndConditionsManagerObserver;
NS_ASSUME_NONNULL_BEGIN
@interface TermsAndConditionsReader : GenericInteractor <TermsAndConditionsReader>
INTERACTOR_INIT_UNAVAILABLE;
- (instancetype)initWithUserAccountManager:(UserAccountManager*)userAccountManager
termsAndConditionsManager:(TermsAndConditionsManager*)termsAndConditionsManager
appId:(NSUInteger)appId NS_DESIGNATED_INITIALIZER;
@property (nonatomic, strong, readonly) UserAccountManager* userAccountManager;
@property (nonatomic, strong, readonly) TermsAndConditionsManager* termsAndConditionsManager;
@end
NS_ASSUME_NONNULL_END
条款和条件Reader.m
@interface TermsAndConditionsReader () <TermsAndConditionsManagerObserver>
@property (nonatomic, assign) NSUInteger appId;
@end
@implementation TermsAndConditionsReader
@synthesize listener = _listener;
- (instancetype)initWithUserAccountManager:(UserAccountManager*)userAccountManager
termsAndConditionsManager:(TermsAndConditionsManager*)termsAndConditionsManager
appId:(NSUInteger)appId {
self = [super init];
if (self) {
_userAccountManager = userAccountManager;
_termsAndConditionsManager = termsAndConditionsManager;
[termsAndConditionsManager addTermsAndConditionsManagerObserverWithObserver:self];
_appId = appId;
}
return self;
}
- (BOOL)areTermsAndConditionsAccepted {
id<UserAccount> userAccount = self.userAccountManager.userAccount;
return [userAccount hasAcceptedTermsAndConditionsForApp:self.appId];
}
#pragma mark - TermsAndConditionsManagerObserver
- (void)termsAndConditionsManagerUserNeedsToAcceptNewTermsWithSender:(TermsAndConditionsManager * _Nonnull)sender {
[self.listener termsAndConditionsReaderNewTermsAndConditionsHasToBeAccepted:self];
}
@end
TermsAndConditionsReader.swift --> 这可能是错的,这就是我试图转换它的方式
@objc public class TermsAndConditionsReader: GenericInteractor, TermsAndConditionsReaderProtocol, TermsAndConditionsManagerObserver {
let userAccountManager: UserAccountManager
let termsAndConditionsManager: TermsAndConditionsManager
let appId: UInt
public var listener: AnyObject & TermsAndConditionsListener
@objc public init(userAccountManager: UserAccountManager, termsAndConditionsManager: TermsAndConditionsManager, appId: UInt) {
self.appId = appId
self.userAccountManager = userAccountManager
self.termsAndConditionsManager = termsAndConditionsManager
termsAndConditionsManager.addTermsAndConditionsManagerObserver(observer: self) // -> It complains here because I am calling self before having initialised listener
}
// MARK: - TermsAndConditionsReaderProtocol
@objc public func areTermsAndConditionsAccepted() -> Bool {
return self.userAccountManager.userAccount?.hasAcceptedTermsAndConditions(forApp: self.appId) ?? false
}
// MARK: - TermsAndConditionsManagerObserver
@objc public func termsAndConditionsManagerUserNeedsToAcceptNewTerms(sender: TermsAndConditionsManager) {
// call listener here:
}
}
交互者条款和条件.h
@protocol TermsAndConditionsListener <NSObject>
- (void)termsAndConditionsReaderNewTermsAndConditionsHasToBeAccepted:(id<TermsAndConditionsReader>)sender;
@end
@protocol TermsAndConditionsReader <NSObject>
@property (nonatomic, weak, nullable) id<TermsAndConditionsListener> listener;
- (BOOL)areTermsAndConditionsAccepted;
@end
InteractorsTermsAndConditions.swift -> 这就是我翻译它的方式
@objc public protocol TermsAndConditionsListener {
@objc func termsAndConditionsReaderNewTermsAndConditionsHasToBeAccepted(sender: TermsAndConditionsReaderProtocol)
}
@objc public protocol TermsAndConditionsReaderProtocol {
@objc var listener: AnyObject & TermsAndConditionsListener { get set }
@objc func areTermsAndConditionsAccepted() -> Bool
}
解决方案
您不能ProtocolA
在实现中用作类型Class1
;您需要声明另一个Class2: ProtocolA
并将其用作您的variableNameB
在您的代码上下文中,您需要声明
// rename your listener protocol
protocol TermsAndConditionsListenerProtocol {
// whatever requirements
}
// implement a concrete type that conforms to this protocol
class TermsAndConditionsListener: TermsAndConditionsListenerProtocol {
// implement requirements
// as well as any init you need
init(hello: String) { /* ... */ }
}
// adjust your reader protocol
protocol TermsAndConditionsReaderProtocol {
var listener: TermsAndConditionsListenerProtocol { get set }
func areTermsAndConditionsAccepted() -> Bool
}
// implement a concrete reader that conforms to reader protocol
class TermsAndConditionsReader: TermsAndConditionsReaderProtocol {
// here you use a concrete type that conforms to the listener protocol
var listener: TermsAndConditionsListener = .init(hello: "world")
// + other requirements
}
推荐阅读
- sql-server - Len 函数:unicode 字符计为 2
- firebase-test-lab - Firebase 测试实验室错误“放弃会话的意外错误”
- amazon-web-services - 具有 ECS 蓝/绿部署的 AWS CodePipeline 因内部错误而失败
- apollo - apollo 服务器从 apollo 上传客户端接收空对象
- angular - 修改一个查询参数:express JS get请求
- php - 如何修复“require_once() 无法打开流”
- ansible - Ansible - 无法通过 ssh 连接到主机:权限被拒绝(公钥,...密码)
- dart - 多次打开页面错误
- ios - 在 App Messaging 的 Firebase 中添加两个按钮
- javascript - 将圆圈添加到svg时如何最小化回流