一个毫无道理的iOS问题

2,301 阅读2分钟

昨天晚上在朋友圈看到某猿发了这样一张图片:

莫名其妙的问题.png

提问:代码1和代码2的执行结过是什么?

刚开始在朋友圈看到这个问题,以为是指针重指向产生野指的问题。但是亲自编译了一下发现并不是。

测试后发现这段代码的问题是这样的:

  1. 代码1执行后并不会崩溃,代码2执行后会崩溃。
  2. 只有使用initWithUTF8String方法创建NSString会崩溃
  3. 只有字符串的内容长度超过10字节才会奔溃崩溃
  4. 代码放到子线程或者做延时操作都会崩溃

测试过之后我就在想,为什么同样的代码因为字符串的长度不同就会产生不同的结果呢?

首先我觉得是因为string1被释放之后,string2被重新创建或是重指向什么的。 然后就有个下边两个图片:

崩溃内存.png

这是崩溃代码的内存地址

不崩溃内存.png

这是不崩溃代码的内存地址

然后我发现这个问题和重指向并没有什么太大关系

然后我就猜想难道是运行时搞的鬼?或者是苹果的优化机制(PS:当代码不满足或者满足某个条件就直接跳到结果)? 然而这些猜想都没有办法去测试,只能在其他方向找原因了。

然后我又尝试了将创建的属性声明改成统一的,比如weak,copy,strong。 就像这样:

@property (nonatomic, strong) NSString *string1;
@property (nonatomic, strong) NSString *string2;

这样:

@property (nonatomic, weak) NSString *string1;
@property (nonatomic, weak) NSString *string2;

或者这样:

@property (nonatomic, copy) NSString *string1;
@property (nonatomic, copy) NSString *string2;

果然不管怎么执行都不会崩溃了。

真神奇,然后发现。本来只有一个问题的我,现在变成两个了,想死。

  1. 为什么代码2会产生奔溃
  2. 为什么换成其他关键字修饰就不会崩溃了

截止到目前为止并没有发现比较靠谱的解释,我会持续寻找答案,然后更新到这。