我有一个类,它复制一个 NSString 并打印它的保留计数和地址。
@interface TestStringPointer : NSObject
@property (copy) NSString *stringTest;
- (void)printPointer;
@end
@implementation TestStringPointer
- (void)printPointer {
NSLog(@"PrintPointer:%p\n RetainCount:%lu", _stringTest, [_stringTest retainCount]);
}
@end
在我的主要功能中,我对字符串的指针进行了一些调查并遇到了一个问题。
int main(int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
TestStringPointer *test = [[TestStringPointer alloc] init];
NSString *myString = [NSString stringWithUTF8String:"Hello World"];
NSLog(@"MyString: %p \n RetainCount:%lu", myString, [myString retainCount]);
[test setStringTest:myString];
[test printPointer];
[myString release];
[pool drain];
while (1) {
[test printPointer];
}
return 0;
}
当我调试应用程序时,它通过 while 循环第三次崩溃(通过循环的次数不同)。我知道复制不会发生,因为字符串不可变。在 main 发布后,我预计它会回到 1。
1)如果一个对象没有自动释放,它是否仍然影响自动释放池?
2) 拥有最大保留计数不会阻止对象在池中被耗尽,还是将其标记为删除?
3)副本不应该在某个时候介入并在被删除之前实际制作副本吗?
StringPointerTest[2253:303] MyString: 0x100100f60 RetainCount:1
StringPointerTest[2253:303] PrintPointer:0x100100f60 RetainCount:2
StringPointerTest[2253:303] PrintPointer:0x100100f60 RetainCount:1152921504606846975
StringPointerTest[2253:303] PrintPointer:0x100100f60 RetainCount:1152921504606846975
如果我修改 main 并删除池
int main(int argc, const char * argv[])
{
TestStringPointer *test = [[TestStringPointer alloc] init];
NSString *myString = [NSString stringWithUTF8String:"Hello World"];
NSLog(@"MyString: %p \n RetainCount:%lu", myString, [myString retainCount]);
[test setStringTest:myString];
[test printPointer];
[myString release];
while (1) {
[test printPointer];
}
return 0;
}
一切都好……永远……
StringPointerTest[423:303] MyString: 0x10010a670 RetainCount:1
StringPointerTest[423:303] PrintPointer:0x10010a670 RetainCount:2
StringPointerTest[423:303] PrintPointer:0x10010a670 RetainCount:1
...