当前位置:   iOS > 正文

为什么isKindOfClass和isMemberOfClass与NSString和NSMutableString一起工作不好?

class,objective-c-runtime,nsstring,nsmutablestring,ios,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在线开发工具,前端开发工具,开发人员工具,站长工具

我知道Apple警告不要使用它.但鉴于他们的推理,结果远非相关和预期.

这是我的调试输出 - 代码中的结果没有区别 - 下面只是为了简洁:

(lldb) po [@"Hello" isKindOfClass:[NSMutableString class]]
true => A mutable string?

(lldb) po [[@"Hello" mutableCopy] isKindOfClass:[NSMutableString class]]
0x00000001019f3201   => What's that?

(lldb) po [[@"Hello" mutableCopy] isMemberOfClass:[NSMutableString class]]
0x000000010214e400   => What's that?

(lldb) po [@"Hello" isMemberOfClass:[NSMutableString class]]
false  => Once again?

除此之外,我删除了所有字符串文字代码并测试了以下内容:

NSMutableString * m = [[NSMutableString alloc] initWithString:@"Hello"];

bool b = [m isKindOfClass:[NSMutableString class]];
NSLog(@"%d", b); --> 1 Expected.
b = [m isKindOfClass:[NSString class]];
NSLog(@"%d", b); --> 1 Expected.
b = [m isMemberOfClass:[NSString class]];
NSLog(@"%d", b); --> 0 Expected.
b = [m isMemberOfClass:[NSMutableString class]];
NSLog(@"%d", b); --> 0 Not Expected.

有启发吗?

更新:

Apple自己采取的措施:

在类集群表示的对象上使用此方法时要小心.由于类集群的性质,您获得的对象可能并不总是您期望的类型.如果调用返回类集群的方法,则该方法返回的确切类型是您可以对该对象执行的操作的最佳指示.

为什么不简单地说不使用isKindOfClassisMemberOfClass集群类?

该解释阻止了从以下角度使用:

你最终可能会修改一些你不应该做的事情.

而不是陈述:

这些方法不适用于类集群.(在示例中,我已经在上面显示 - 我显然正在传递正确的对象,但仍未获得预期的结果.)

更新2:

提起Apple雷达.



1> Ken Thomases..:

这些方法不会像您在评论中声称的那样"误导".因为NSString并且NSMutableString是类集群,所以它们可以返回任何具体子类的实例,分别是-a NSStringNSMutableString.

碰巧,NSString集群中的大多数具体子类也是其子类NSMutableString.他们不使用实际的类来控制可变性,而是使用标志或类似的东西.一切都完全有效并符合设计合同.

所以,这就是为什么[@"Hello" isKindOfClass:[NSMutableString class]]返回true.你问"一个可变的字符串?" 不.该表达式不是可变性的有效测试.据记载,没有有效的可变性测试.这是你误解的核心.您不得尝试询问对象的类以确定它是否可变.您必须遵守API中指针的静态类型.


编辑:这在Objective-C编程中的概念中记录:对象可变性 - 接收可变对象:

使用返回类型,而不是自省

为了确定它是否可以改变接收的对象,消息的接收者必须依赖于返回值的正式类型.例如,如果它接收到一个类型为immutable的数组对象,它就不应该尝试改变它.根据类的成员身份确定对象是否可变是不可接受的编程习惯 - 例如:

if ( [anArray isKindOfClass:[NSMutableArray class]] ) {

    // add, remove objects from anArray

}

出于与实施相关的原因,isKindOfClass:在这种情况下返回的内容可能不准确.但是出于其他原因,您不应该根据类成员资格来确定对象是否可变.您的决定应该完全取决于出售该对象的方法的签名对其可变性的描述.如果您不确定对象是可变的还是不可变的,则假设它是不可变的.

几个例子可能有助于澄清为什么这个指南很重要:

您从文件中读取属性列表.当Foundation框架处理列表时,它注意到属性列表的各个子集是相同的,因此它创建了一组在所有这些子集中共享的对象.然后,您查看创建的属性列表对象,并决定改变一个子集.突然间,你没有意识到这一点,你已经在多个地方改变了树.

你要求NSView它的子视图(使用subviews方法),它返回一个声明为一个NSArray但可能是NSMutableArray内部的对象.然后将该数组传递给其他代码,这些代码通过内省确定它是可变的并更改它.通过更改此数组,代码正在改变类的内部数据结构NSView.

所以不要根据内省告诉你的关于对象的内容来假设对象的可变性.根据您在API边界处传递的内容(即基于返回类型)将对象视为可变对象.如果在将对象传递给客户端时需要明确地将对象标记为可变或不可变,请将该信息作为标志与对象一起传递.


正如其他人所提到的那样,-isMemberOfClass:测试是一个确切类的实例,而不是任何子类.对于类集群,它总是返回false,因为公共类是抽象的,永远不会有实例.

其他奇怪的结果可能是因为您正在使用po("打印对象"的缩写)非对象值.将该p命令用于布尔表达式.

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/iOS/detail/8788
推荐阅读
  • 如何解决《在UIButton中创建三角形》经验,为你挑选了0个好方法。uibutton,uiview,cashapelayer,ios,uibezierpath,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,jso... [详细]

  • 如何解决《何时在Swift中使用全局变量》经验,为你挑选了1个好方法。global,global-variables,ios,swift,cocoa,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维... [详细]

  • 如何解决《使用boost::function和boost::bind》经验,为你挑选了1个好方法。c++,boost,ios,linux,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,un... [详细]

  • 如何解决《onEndEditing和onBlur之间的区别?》经验,为你挑选了2个好方法。react-native,ios,android,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,u... [详细]

  • 如何解决《返回值优化和析构函数调用》经验,为你挑选了1个好方法。c++,c++11,容器,ios,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在线开发工具,前端开发工具,... [详细]

  • 如何解决《如何为2D数组编写访问器(私有成员)》经验,为你挑选了1个好方法。c++,accessor,multidimensional-array,ios,go,安全,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,... [详细]

  • 如何解决《括号和赋值运算符顺序》经验,为你挑选了2个好方法。c#,c++,ios,https,git,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在线开发工具,前端开发工... [详细]

  • 如何解决《获取单词和空格字符串中的第一个单词-在空格之前键入第一个单词》经验,为你挑选了2个好方法。ios,swift,安全,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,... [详细]

  • 如何解决《React原生弹性框不使用所有可用空间》经验,为你挑选了1个好方法。android,ios,flexbox,reactjs,react-native,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json... [详细]

  • 如何解决《Hexfloat机械手和精度》经验,为你挑选了1个好方法。c++,precision,hex,c++11,ios,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在... [详细]

  • 如何解决《"无法使用'UITextField'类型的参数列表调用类型'Int'的初始值设定项"是什么意思?》经验,为你挑选了1个好方法。ios,swift,DevBox,在线流程图,编程,... [详细]

  • 如何解决《AVAudioEngine.start()崩溃,即使它包含在do/catch中》经验,为你挑选了0个好方法。ios,avaudiosession,swift,avaudioengine,DevBox,在线流程图,编程,编程问答,程... [详细]

  • 如何解决《在swift中获取单例实例》经验,为你挑选了1个好方法。objective-c,ios,swift,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在线开发工具,前... [详细]

  • 如何解决《检查Unity的互联网连接》经验,为你挑选了1个好方法。c#,android,internet-connection,unity3d,ios,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二... [详细]

  • 如何解决《如何开发一个自定义的UICollectionViewLayout,它具有与自定义单元格交错的列?》经验,为你挑选了1个好方法。ios,swift,android,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工... [详细]

  • 如何解决《如何在swift中的UIScrollView中设置全宽图像》经验,为你挑选了1个好方法。ios,autolayout,swift,容器,go,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二... [详细]

  • 如何解决《如何在IOS中的UIStackView中设置权重》经验,为你挑选了1个好方法。ios,android-linearlayout,uistackview,android,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,... [详细]

  • 如何解决《使用临时寿命差异》经验,为你挑选了3个好方法。c++,ios,svn,debian,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在线开发工具,前端开发工具,开发... [详细]

  • 如何解决《如何分支/切换多个条件?》经验,为你挑选了3个好方法。c++,c++11,ios,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在线开发工具,前端开发工具,开发人... [详细]

  • 如何解决《旋转UIButton360度》经验,为你挑选了4个好方法。uibutton,uiview,ios,swift,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在线开... [详细]

相关标签
  

闽ICP备14008679号