我正在研究内存管理概念。我创建了一个string1
并将该string1
分配给另一个string2
,现在释放此string1
。
在这里,string2
保留计数为1,但是在NSLog
语句中,它赋予EXC错误访问权限。
当我分配字符串时
NSString * string1 = [[NSString alloc]initWithFormat:@"hello"];
string2 = string1;
NSLog(@"string1 memory address = %p, string2 memory address = %p", &string1, &string2);
[string1 release];
NSLog(@"[string2 retainCount] = %lu", (unsigned long)[string2 retainCount]);
NSLog(@"string2 = %@", string2); // here app is crashing
这是否意味着string2也具有自动释放消息,因为如果我执行
string2 = [string1 copy];
而不是string2 = string1;
不会崩溃。所以我想问一下崩溃是否是因为它具有
string2
的自动释放消息,以及它与string2
释放命令有何关系。请指教!
最佳答案
如果您在Objective-C中使用手动内存管理,则分配不会更改对象的保留计数。您一定要使用它,否则,您将无法在代码中调用release
方法。
因此,您的代码执行以下操作。它创建保留计数= 1的NSString
对象,并将其分配给string1
指针。之后,将string1
分配给string2
。现在,您有2个指向同一对象的指针,并且该对象的保留计数仍为1。然后释放对象,立即将其释放。然后,您遇到崩溃:
NSString * string1 = [[NSString alloc]initWithFormat:@"hello"]; // string retain count is 1
string2 = string1; // 2 pointers to same string, retain count is still 1
[string1 release]; // string is deallocated when retain count drops to 0
NSLog(@"string2 = %@", string2); // here app is crashing
要解决此问题,可以在分配作业时使用
retain
。NSString * string1 = [[NSString alloc]initWithFormat:@"hello"]; // string retain count is 1
string2 = [string1 retain]; // 2 pointers to same string, retain count is 2
[string1 release]; // string retain count back to 1
NSLog(@"string2 = %@", string2); // no crash
另外,您可以使用
copy
。请注意,对于NSString
复制实际上并不复制对象,它只是调用retain
。无需执行实际的复制,因为NSString
是不可变的,无法更改。如果我们使用NSMutableString
,情况将会改变:NSMutableString * string1 = [[NSMutableString alloc]initWithFormat:@"hello"]; // string retain count is 1
NSMutableString * string2 = [string1 copy]; // 2 separate strings, both have retain count 1
[string1 release]; // string1 is deallocated
NSLog(@"string2 = %@", string2); // no crash, string2 retain count is 1
或者,您可以使用ARC。它将在编译时插入相应的保留/释放调用。代码如下所示:
NSString * string1 = [[NSString alloc]initWithFormat:@"hello"];
string2 = string1;
string1 = nil;
NSLog(@"string2 = %@", string2); // no crash
我建议先了解手动内存管理,然后再迁移到ARC。
关于ios - iOS发行版和nsstring不同,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39622619/