ObjC: +[NSObject isSubclassOfClass:] 给出不正确的失败

2024-04-01

  • 我有一个 iOS 静态库,它定义了NSOperation客户端应该子类化以添加自己的逻辑的基类:@interface BaseClass : NSOperation

  • 客户向管理器注册他们的子类:-[OperationManagerClass registerClass:forType:]

  • 在管理器中,我想强制您必须注册一个子类BaseClass不只是NSOperation

好吧,看来是断言+isSubclassOfClass:应该完成工作。但是……事实并非如此。

@implementation OperationManagerClass

- (void)registerClass:(Class)aClass forType:(NSString *)type
{
    NSAssert([aClass isSubclassOfClass:[BaseClass class]);

    self.registeredClasses[type] = aClass;
}

@end

断言总是NO,即使通过了BaseClass.

去更高的阶级阶层怎么样?NSOperation and NSObject都回应YES!

(lldb) p (BOOL)[aClass isSubclassOfClass:[BaseClass class]]
(BOOL) $0 = NO
(lldb) po aClass
BaseClass
(lldb) p (BOOL)[aClass isSubclassOfClass:[NSOperation class]]
(BOOL) $2 = YES
(lldb) p (BOOL)[aClass isSubclassOfClass:[NSObject class]]
(BOOL) $3 = YES

请注意,基操作类的使用者在 iOS 应用程序项目中进行子类化,并且OperationManagerClass and BaseClass位于包含的静态库中。为什么我认为这可能与isSubclassOfClass:错了吗?由于以下...

仍在 libSharedStuff.a 中

@implementation OperationManagerClass

- (void)registerClass:(Class)aClass forType:(NSString *)type
{
    // Obviously OperationManagerClass.m cannot #import "OutsideClass.h"
    NSAssert([aClass isSubclassOfClass:NSClassFromString(@"OutsideClass");

    self.registeredClasses[type] = aClass;
}

@end

在应用目标中

@interface OutsideClass : NSOperation
@end

@interface OutsideClassSubA : OutsideClass
@end

...产生以下结果OutsideClassSubA传入:

(lldb) p (BOOL)[aClass isSubclassOfClass:[OutsideClass class]]
(BOOL) $0 = YES
(lldb) po aClass
OutsideClassSubA
(lldb) p (BOOL)[aClass isSubclassOfClass:[NSOperation class]]
(BOOL) $2 = YES
(lldb) p (BOOL)[aClass isSubclassOfClass:[NSObject class]]
(BOOL) $3 = YES

这里发生了什么?为什么+isSubclassOfClass:给出错误答案?我怎样才能强制执行aClass参数必须是我的子类BaseClass?


Edit:
I realized the example I posted works fine after pulling the pieces into a separate Xcode workspace. I've posted the toy source code from above https://github.com/evandelaney/StackOverflow-19883472 with a twist I left out of my original description.

我其实有two静态库(libSharedStuff.a and libHelperSharedStuff.a)。应用程序目标链接libSharedStuff.a,单元测试目标取决于应用程序目标以及链接libHelperSharedStuff.a. When BaseClass.m是的成员both静态库目标,然后+isSubclassOfClass:将在单元测试断言中失败。具体来说,当我通过时它会失败MockBaseClass,它是一个子类BaseClass这是单元测试目标的一部分。

所有这些都在上面链接的项目中进行了说明。


正如我在编辑问题时所解释的那样,我包括BaseClass.m在两个静态库中libSharedStuff.a and libHelperSharedStuff.a。主要应用目标链接libSharedStuff.a和单元测试目标链接libHelperSharedStuff.a。这意味着当.xctest捆绑包在运行时注入到我的应用程序中,BaseClass符号被定义了两次

(或许?那可能吗?运行时实际发生了什么?).

我似乎在我的单元测试目标中MockSubclassOfBaseClass继承自BaseClass符号在libHelperSharedStuff.a,而在我的应用程序目标中SubclassOfBaseClass继承自BaseClass符号在libSharedStuff.a。如果是这样的话,那就有道理了+isSublcassOfClass:回应NO when MockSubclassOfBaseClass已传入!

任何澄清、证实或提供更好的见解的答案都非常感谢我在这里有正确的想法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ObjC: +[NSObject isSubclassOfClass:] 给出不正确的失败 的相关文章

  • NSURL URLWithString:引发异常

    简而言之 NSURL URLWithString 似乎引发了一个例外 根据文档 如果字符串格式错误 则返回 nil 没有提到在任何情况下都会引发异常 除此之外 我还对 URL 进行编码并检查nil在将字符串转换为 URL 之前 任何人都可以
  • GMSMapView 中的倒多边形

    我必须在我的 iPhone 项目中使用 Google 地图 并且我正在使用 GMSPolygon 来绘制多边形 但是如何填充地图上除多边形内部之外的所有位置 就像下图一样 谢谢 我玩过你的问题 主要思想是用多边形填充整个地球 然后为您的特定
  • 用 UIView 像翻书一样翻页?

    我正在尝试在之间切换UIViews让它看起来就像你正在翻书的一页 The UIViewAnimationTransitionCurlUp如果我能让它向左或向右卷曲 那就非常接近了 这可能吗 我尝试过使用CATRansition但没有一种动画
  • Objective-C / C 给出枚举默认值

    我在某处读到过关于给枚举默认值的内容 如下所示 typedef enum MarketNavigationTypeNone 0 MarketNavigationTypeHeirachy 1 MarketNavigationTypeMarke
  • Swift 3 错误:[_SwiftValue pointSize] 无法识别的选择器发送到实例

    我刚刚将我们的项目迁移到 swift 3 发现由于一个问题导致大量崩溃 由于未捕获的异常 NSInvalidArgumentException 而终止应用程序 原因 SwiftValue pointSize 发送到实例的无法识别的选择器 该
  • UITextFieldDelegate 与 UITextField 控件事件

    如果我想处理 UITextField 的更改 例如用户在其中键入 看起来这可以通过将委托分配给该文本字段 然后让委托实现 shouldChangeCharactersInRange 来完成 或者通过将目标添加到文本字段并处理 UIContr
  • iOS 11 安全区域布局指南向后兼容性

    启用安全区域布局指南是否与 iOS 11 以下版本兼容 我设法使用新的安全区域布局指南并保持与 iOS 9 和 iOS 10 的向后兼容性 编辑 正如 NickEntin 的评论所指出的 此实现将假定存在状态栏 但在 iPhone X 的横
  • iOS中的performSelector有什么用

    的作用是什么执行选择器 比较 self btnClicked and self performSelector selector btnClicked void btnClicked NSLog Method Called 两者都对我来说工
  • ITMS-90535 无法使用最新的 Google Signin SDK 发布 iOS 应用程序

    我正在使用 xcode 7 GM 种子并通过 cocoapods 安装了最新的 Google Signin SDKpod Google SignIn 当我尝试将我的应用程序发布到苹果应用程序商店时 我收到附加错误 Help 以下是 Goog
  • 适用于 Objective-C / iPhone 的良好 HTTP 库? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 UPDATE 这个问题显然已经过时了 参见日期 我建议只使用现代 iOS7 功能 例如 NSURLSession 我想 这个问题是为了历史
  • 在后台任务中安排通知

    我正在为 iOS 开发一个日历 闹钟应用程序 它与网络服务器同步 当在服务器上添加活动时 会发出推送通知 以便 iOS 客户端可以获取新数据 并根据需要更新和安排下一次警报的时间 本地通知 但这仅在应用程序在客户端打开时才有效 我希望客户端
  • 无法使用 Xamarin 和 WCF 访问 Web 服务

    我想使用 Xamarin 和 WCF 来使用公共 Web 服务 对于这个演示 我将使用Xamarin iOS 这是我试图使用的 公共 网络服务 http www webservicex net globalweather asmx WSDL
  • SpriteKitPhysicsBody非矩形碰撞

    pipeUp physicsBody SKPhysicsBody rectangleOfSize pipeUp size 在此编码中我使用了rectangleOfSize对于碰撞物理体 但如果我想按像素仅使用图像的形状 我应该使用什么而不是
  • PrepareForSegue之谜

    我在两个不同的 VC 中有一个prepareForSegue 方法 一个使用一个if声明 而另一个旨在使用switch 除了名称之外 代码几乎相同 这个效果很好 void prepareForSegue UIStoryboardSegue
  • 应用程序传输安全已禁用,但仍然出现 SSL 握手错误

    我在通过 HTTPS SSL 连接到 API 时遇到问题 我已经使用下面的字典完全禁用了应用程序传输安全性 ATS 尽管 SSL 证书通过了 NSCURL 的所有测试
  • iOS WKWebView.scrollView委托导致BAD_ACCESS

    我的 viewController 有一个 UIView 属性 其中包含一个 WKWebView 我将 WKWebView rollView 委托设置为我的 viewController 它是我的 UIView 子类的公共函数 并在我的 v
  • 我什么时候应该对 IBOutlet 使用弱或强限定符? [复制]

    这个问题在这里已经有答案了 可能的重复 ARC 下 IBOutlets 应该强还是弱 https stackoverflow com questions 7678469 should iboutlets be strong or weak
  • Xcode 9 中的“addingPercentEncoding”是否损坏?

    在 Swift 3 x 和 Xcode 9 beta 2 中 使用addingPercentEncoding https developer apple com documentation swift string 1690785 addi
  • NSPredicate 的 onFormat 字符串

    我想用 id 键对数据进行排序 我如何理解格式字符串的用途NSPredicate格式 我有一个100号的帖子 我的代码 let objectIDs posts map 0 id let predicate NSPredicate forma
  • 如何通过辅助功能 API 获取当前所选文本的全局屏幕坐标。

    我需要帮助来了解字典应用程序如何在任何应用程序上按 CMD CTRL D 时显示所选文本的以下弹出对话框 我想实施 我的可可应用程序具有相同的功能 我的应用程序将在后台运行 并显示有关所选文本的一些热键的建议 我已经实现了热键捕获 我只需要

随机推荐