目标C-自调零弱指针意外行为 [英] Objective C - Self Zeroing weak pointer unexpected behaviour

查看:80
本文介绍了目标C-自调零弱指针意外行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近从小牛队升级到优胜美地,现在我的单元测试失败了.这个问题归结为字符串内容的弱指针中的错字.请参见以下示例代码:

I have recently upgraded from Mavericks to Yosemite and now my unit tests are failing. The problem boiled down to a typo in a weak pointer to string content. Please see the following sample code:

NSString* value1;
NSString* value2;
__weak NSString* weakValue1;
__weak NSString* weakValue2;
NSMutableString* resultText = [NSMutableString new];

@autoreleasepool
{
    value1 = [NSString stringWithFormat: @"Hello: %d", 1];
    value2 = [NSString stringWithFormat: @"Hello %d", 2];
    weakValue1 = value1;
    weakValue2 = value2;

    [resultText appendFormat: @"  value1 = %@", weakValue1];
    [resultText appendFormat: @"  value2 = %@", weakValue2];

    value1 = nil;
    value2 = nil;
}
[resultText appendFormat: @"  value1 = %@", weakValue1];
[resultText appendFormat: @"  value2 = %@", weakValue2];

NSLog( @"resultText = %@", resultText );

此代码的输出是:

resultText =   value1 = Hello: 1  value2 = Hello 2  value1 = (null)  value2 = Hello 2

我原本期望:

resultText =   value1 = Hello: 1  value2 = Hello 2  value1 = (null)  value2 = (null)

第二个value2也是(null),但不是.请注意value1value2的内容之间的区别. value2缺少冒号.我不明白为什么当value2设置为nilweakValue2不自零.一旦将冒号放回字符串中,就会得到我期望的结果.在Mavericks中运行此代码时,我没有看到这种行为.

the second value2 to also be (null) but it is not. Please notice the difference between the content of value1 and value2. value2 is missing the colon. I do not understand why weakValue2 does not self zero when value2 is set to nil. As soon as I put the colon back in the string I get the results I expect. I was not seeing this behaviour when running this code in Mavericks.

有人知道为什么会这样吗?

Does anyone know why this is happening?

我在此问题中注意到有效点多线程操作可能会导致弱指针无法及时自我归零,但事实并非如此.首先,我不是多线程的,如果我单步执行代码并查看变量而不是使用NSLog打印它们,则会得到完全相同的结果.

I noticed in this question that the valid point of multithreading could cause a weak pointer to not self zero in time, but that is not what is happening here. Firstly, I am not multithreaded and I get the exact same result if I step through the code and view the variables rather than printing them with NSLog.

推荐答案

NSString这不是具体的类,它是许多其他类的接口和工厂.

NSString it is not concrete class, it is interface and factory for many other classes.

我发现value1是__NSCFString类的实例,但是value2是NSTaggedPointerString类的实例. NSTaggedPointerString类不支持保留和释放(我尝试向其方法注入一些块).

I've found that value1 is instance of class __NSCFString, but value2 is instance of class NSTaggedPointerString. Class NSTaggedPointerString does not support retain and release (I try to inject some blocks to it methods).

如果您为此实例打印keepCount,则会得到该结果:

If you print retainCount for this instance, you'll get that result:

po [value2 retainCount] //18446744073709551615

如果从格式中删除符号:",则会得到以下结果:

If you remove symbol ":" from format, you'll get this result:

 resultText =   value1 = Hello 1  value2 = Hello 2  value1 = Hello 1  value2 = Hello 2

发生这种情况是因为上面的字符串是NSTaggedPointerString类的实例.我认为这是非常奇怪的行为.

It's happened because above strings is instances of NSTaggedPointerString class. I think it is very strange behaviour.

P.S.

如果在value2字符串中添加:",则会得到结果:

If you add ":" to value2 string, you'll get result:

resultText =   value1 = Hello: 1  value2 = Hello: 2  value1 = (null)  value2 = (null)

:)

UPD

如果字符串的长度小于8,则它将字符串缓存到内存中.

If length of string less then 8, then it string will be cached to memory.

UPD-2

我已将代码更改为:

value1 = [NSString stringWithFormat: @"Heo: %d", 1];
    value2 = [NSString stringWithFormat: @"Heo: %d", 1];
    if (value2 == value1)
    {
        NSLog(@"same strings");
    }

我得到的结果是:相同的字符串"

I've had result: "same strings"

这篇关于目标C-自调零弱指针意外行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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