objective-c - 超类的init方法为NS_UNAVAILABLE时如何初始化子类
问题描述
我正在尝试为objective-c 类编写测试。我要测试的类是MyClass
,它看起来像这样:
@interface MyClass : NSObject
- (void)dispatchEvent:(IMAAdEvent *)event;
@end
为了测试这个dispatchEvent
方法,我需要传入一个IMAAdEvent
. 该类IMAAdEvent
来自谷歌的图书馆GoogleAds-IMA-iOS-SDK
。
不幸的是,我不能调用init
这个类,因为 init 方法被标记为NS_UNAVAILABLE
. 在 XCode 中,我收到一个反映这一点的错误:
'init' 不可用
理想情况下,我想制作自己的这样的模拟子类IMAAdEvent
。有什么方法可以在不调用超类上不可用的 init 方法的情况下初始化我的子类?:
@interface MockImaAdEvent : IMAAdEvent
@end
@implementation MockImaAdEvent
- (id)init {
// is there something I can do here so that I return an instances
// of the subclass without calling [super init]?
}
@end
解决方案
从 Xcode 12.5 开始,Swift 不再能够使用以前的解决方案。编译器已开始为添加了新函数init() is unavailable
的代码行返回错误。init
Xcode 12.5 发行说明指出以下内容:
Clang 现在从 -init 方法上的可用性注释推断 +new 的可用性。由于 +new 调用 [[Foo alloc] init],所以 +new 不可用,除非 +init 可用。
尽管有此发行说明,但仍有一个有效的解决方法。通过在 Objective-C 中编写模拟类并使用桥接头将其引入 Swift,模拟类仍然可以调用super.new
以获取父类的新实例(然后从那里自定义子类)。
这是一个例子:
@interface MockInAppMessagingCampaignInfo ()
@property (strong, nonatomic) NSString *campaignNameValue;
@end
@implementation MockInAppMessagingCampaignInfo
+ (id)newWithCampaignName:(NSString *)campaignName {
MockInAppMessagingCampaignInfo *newObject = super.new;
newObject.campaignNameValue = campaignName;
return newObject;
}
- (NSString *)campaignName {
self.campaignNameWasCalled = YES;
return self.campaignNameValue ?: @"";
}
@end
推荐阅读
- c# - 如何将“XX,XXX”替换为“XX XXX”?
- javascript - 在选择器中转义反斜杠
- java - 如何在没有任何背景的情况下使用 android 启动器图标
- oracle - Sqlldr tab delim 文件加载问题
- angular - 通过在 typescript 中调用方法打开 bootstrap 4 模态
- java - NoSuchMethodError 当不直接调用方法,而是服务方法时
- formula - 将整数值分配给相对值列表
- c# - 单元测试时无法调试 dll - 未命中断点且无法更改属性中的配置
- asp.net - 无法在 asp .net core signalR 中播放示例客户端到服务器流式传输示例
- sql-server - 选择查询逻辑sql server