Objective-C - 为啥添加两个字符串会导致崩溃?
Posted
技术标签:
【中文标题】Objective-C - 为啥添加两个字符串会导致崩溃?【英文标题】:Objective-C - why adding two string is causing the crash?Objective-C - 为什么添加两个字符串会导致崩溃? 【发布时间】:2017-03-08 23:27:50 【问题描述】:将新字符串附加到旧字符串会导致崩溃。
(如果我这样做Structios.server = @""; StructIOS.server = [StructIOS.server stringByAppendingString:@".***.com"];
,则异常有效)。
struct.h:
struct iOS
__unsafe_unretained NSString *input_url;
__unsafe_unretained NSString *use_url;
__unsafe_unretained NSString *server;
;
struct iOS StructIOS;
ViewController.m:
StructIOS.use_url = @"relay/pincode/apicode/accesskey/1/2/3/99/../900";
NSArray *work_array = [StructIOS.use_url componentsSeparatedByString:@"/"];
StructIOS.server = [work_array objectAtIndex:0];
if([StructIOS.server length] > 0)
NSLog(@">>> 4: %@", StructIOS.server); // OK!!
StructIOS.server = [StructIOS.server stringByAppendingString:@".***.com"]; // FAIL!!
NSLog(@">>> 5: %@", StructIOS.server);
输出:
>>> 4: relay
crash
预期输出:
>>> 5: relay.***.com
编辑:以下方式工作没有崩溃
NSString *fool_ios;
// read from NSString type
StructIOS.server = fool_ios;
// save to NSString type
fool_ios = StructIOS.server;
【问题讨论】:
【参考方案1】:答案有两个:
不要将对象存储在 Objective-C 结构中。 ARC 不会为他们管理内存。 请勿使用 unsafe_unretained,除非您完全了解它的作用以及您需要它的确切原因。只需将变量设为类的实例变量即可。这将使它们变得强大,这就是您想要的。
编辑:
请注意,在 Swift 中,将对象存储在 Struct 中是有效的。 Swift 能够在结构中对它们进行内存管理,而 C 则不能。
任何时候编译器强制你使用 __unsafe_unretained,你都可能做错了什么。 (也有例外,但在你的理解水平上,你应该假装 __unsafe_unretained 不存在。)
【讨论】:
【参考方案2】:为什么它们是 __unsafe_unretailed? componentsSeparatedByString() 可能会在内部创建一些由于使用 __unsafe_unretained 而您没有拥有所有权的子字符串,因此当 componentsSeparatedByString 函数超出范围时它们将被删除。 第 4 行的日志工作纯粹是机会和好运,因为字符串已被释放,但仍然存在于该内存位置。 如果将结构重写为一个简单的类(继承自 NSObject),它应该可以工作。
【讨论】:
i.imgur.com/BfaoqfM.png - 当我删除它时,我得到编译错误:/Users/sun/Desktop/iphone/Objective-C_ios10/ios-demo/Struct.h:11:13: ARC forbids Objective-C objects in struct
其实ARC是禁止在struct中使用objective-c对象的,所以你应该把struct重写为一个简单的类。
OK - 所以它的核心 Objective-C 问题。谢谢你,我会的。
你可能还想做一些事情,比如在 Xcode 设置中启用 malloc scribble 和僵尸,这可以帮助检测到这样的事情(如果你只是在某个地方使用了 StructIOS.server 而没有附加它,你就不会发现这个问题,直到它在某处随机崩溃,malloc scribble 和zombies 等将有助于及早发现它)。这些选项在构建方案中可用。
好的,谢谢。 (当我这样做时很尴尬NSString *fool_ios = [StructIOS.server stringByAppendingString:@".***.com"]; StructIOS.server = fool_ios;
)以上是关于Objective-C - 为啥添加两个字符串会导致崩溃?的主要内容,如果未能解决你的问题,请参考以下文章