Cocoa:测试来查找NSString是不可变的还是可变的? [英] Cocoa: Testing to find if an NSString is immutable or mutable?

查看:114
本文介绍了Cocoa:测试来查找NSString是不可变的还是可变的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这会产生一个不可变的字符串对象:

This produces an immutable string object:

NSString* myStringA = @"A";  //CORRECTED FROM: NSMutableString* myStringA = @"A";

这会产生一个可变字符串对象:

This produces a mutable string object:

NSMutableString* myStringB = [NSMutableString stringWithString:@"B"];
But both objects are reported as the same kind of object, "NSCFString":
NSLog(@"myStringA is type: %@, myStringB is type: %@", 
[myStringA class], [myStringB class]);

那么什么是在内部区分这些对象,如何测试,确定一个神秘的字符串变量在做一些邪恶之前是不可变的还是可变的?

So what is distinguishing these objects internally, and how do I test for that, so that I can easily determine if a mystery string variable is immutable or mutable before doing something evil to it?

推荐答案

文档包括一个相当长的解释为什么苹果不想让你这样做,为什么他们明确不支持它在接收可变对象。总结是:

The docs include a fairly long explanation on why Apple doesn't want you to do this and why they explicitly do not support it in Receiving Mutable Objects. The summary is:


所以不要对对象做出决定
可变性基于什么内省
告诉你关于一个对象。将
对象视为可变对象,或者不根据
在API
边界(即基于
返回类型)处理的对象。如果你需要
明确地将一个对象标记为
mutable或immutable,当你将它
传递给客户端,传递信息作为一个
标志与对象。

So don’t make a decision on object mutability based on what introspection tells you about an object. Treat objects as mutable or not based on what you are handed at the API boundaries (that is, based on the return type). If you need to unambiguously mark an object as mutable or immutable when you pass it to clients, pass that information as a flag along with the object.

我发现他们的NSView示例最容易理解,它说明了一个基本的Cocoa问题。你有一个称为元素的NSMutableArray,你想要作为数组暴露,但不希望调用者混乱。您有几个选项:

I find their NSView example the easiest to understand, and it illustrates a basic Cocoa problem. You have an NSMutableArray called "elements" that you want to expose as an array, but don't want callers to mess with. You have several options:


  1. 将NSMutableArray显示为NSArray。

  2. 可变的副本

  3. 将元素存储为NSArray,并在每次变异时创建一个新数组。

我已经在各个方面做了所有这些。 #1是目前为止最简单,最快的解决方案。这也是危险的,因为数组可能突变在调用者的背后。但苹果表示这是他们在某些情况下做的警告(注意 - NSView中的子视图)。我可以确认,虽然#2和#3更安全,他们可以创建主要的性能问题,这可能是为什么苹果选择不使用它们访问的成员如-subviews。

I've done all of these at various points. #1 is by far the simplest and fastest solution. It's also dangerous, since the array might mutate behind the caller's back. But Apple indicates it's what they do in some cases (note the warning for -subviews in NSView). I can confirm that while #2 and #3 are much safer, they can create major performance problems, which is probably why Apple has chosen not to use them on oft-accessed members like -subviews.

所有这一切的结果是,如果你使用#1,那么内省会误导你。你有一个NSMutableArray转换为NSArray,内省将指示它是可变的(内省没有办法知道否则)。但你不能改变它。只有编译时类型检查才能告诉你,所以它是你唯一可以信任的。

The upshot of all of this is that if you use #1, then introspection will mislead you. You have an NSMutableArray cast as an NSArray, and introspection will indicate that it's mutable (introspection has no way to know otherwise). But you must not mutate it. Only the compile-time type check can tell you that, and so it's the only thing you can trust.

这个修复是一种快速拷贝 - 编写一个可变数据结构的不可变版本。这样的方式#2可能做得体面的表现。我可以想象对NSArray集群的更改将允许这一点,但它不存在于Cocoa今天(并可能影响NSArray性能在正常情况下,使其成为非初始)。即使我们有它,也许有太多的代码,依赖于当前的行为,允许可变性内省信任。

The fix for this would be some kind of fast copy-on-write immutable version of a mutable data structure. That way #2 could possibly be done with decent performance. I can imagine changes to the NSArray cluster that would allow this, but it doesn't exist in Cocoa today (and could impact NSArray performance in the normal case, making it a non-starter). Even if we had it, there's probably too much code out there that relies on the current behavior to ever allow mutability introspection to be trusted.

这篇关于Cocoa:测试来查找NSString是不可变的还是可变的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆