Iphone Objective-C指针/内存管理问题
我正在测试下面的代码。ffv在接口文件中声明Iphone Objective-C指针/内存管理问题,iphone,objective-c,ios,pointers,memory-management,Iphone,Objective C,Ios,Pointers,Memory Management,我正在测试下面的代码。ffv在接口文件中声明 ffv = [[FullFunctionView alloc] initWithFrame:self.view.bounds]; NSLog(@"%i", [ffv retainCount]); // prints 1 [self.view insertSubview:ffv belowSubview:switchViewsBtn]; NSLog(@"%i", [ffv retainCount]); // prints 2 [ffv releas
ffv = [[FullFunctionView alloc] initWithFrame:self.view.bounds];
NSLog(@"%i", [ffv retainCount]); // prints 1
[self.view insertSubview:ffv belowSubview:switchViewsBtn];
NSLog(@"%i", [ffv retainCount]); // prints 2
[ffv release]; // you can release it now since the view has ownership of ffv
NSLog(@"%i", [ffv retainCount]); // prints 1
if (ffv == nil)
NSLog(@"ffv is nil");
// "ffv is nil" is not printed
[ffv testMethod]; // "test method called" is printed
这是我的[ffv testMethod]实现
- (void)testMethod
{
NSLog(@"test method called");
}
在这种情况下,我推断,即使您释放了一个带有retaincount 2的对象,您也会失去该对象的所有权,但是引用仍然保留
现在,我的问题是:
在保留计数变为0之前,不会解除分配对象。只要它没有被解除分配,你就可以毫无困难地继续使用它。通过保留它,你可以确保它不会在你脚下被转让;但是,如果您保留了另一个对象,而您知道该对象保留了第一个对象,那么您可以通过这种形式的“间接保留”逃脱。不过,当你晚些时候搬家,事情开始破裂时,不要抱怨。嗯,我不确定“失去”所有权是正确的说法。在Objective-C中,您必须仔细整理对象的所有权。如果创建或保留对象,则负责释放它(直接释放或通过自动释放池释放)。然而,当您调用release时,您不会丢失对该对象的引用,如果其他对象保留了它,它仍将在内存中,并且您的指针仍可能指向它 有一个指针ffv,它只是指向某个内存的指针,还有在ffv指向的第一行中创建的对象 通过调用
release
,您表示您不再需要ponter ffv指向有效对象,在这种情况下,您将很乐意释放该对象。指针仍然指向该内存位,并且它仍然在那里,因为它的保留计数是通过将其分配给视图而增加的
行[ffv testMethod]
有不工作的危险,因为它跟随发布
,并且可能没有指向有效的对象。它之所以有效,是因为有别的东西让它活着。ffv仍然具有第一次分配时的相同地址值
因此,按顺序:
释放
呼叫后使用ffv。你不能保证物体会在你身边李>
这里使用的是指针,而不是Java或C#中的引用。你必须封送你对对象的所有权,你创建它,有一些指向它的指针,通过仔细管理retain和release调用,你可以在内存中保存它,直到你需要它为止 在您释放了
ffv
之后,使用它会出现一些问题,并且它只会被视图控制器的视图保留
1) 它引入了未来可能出现的bug,因为稍后您可能不会记得ffv
在其他情况下不会被保留。释放视图时(例如,通过将其替换为另一个视图),您仍然有一个悬挂的指针,您仍然持有对该指针的引用
2) 在UIViewController
的特殊情况下,可以随时释放视图(您通常不会自己调用viewDidUnload
)。当收到内存警告且视图当前不可见时,UIViewController
的默认行为是释放视图,因此除非在viewDidUnload
中将引用设置为nil,否则即使您自己从未显式释放视图,也会再次出现悬空指针
if (ffv == nil)
NSLog(@"ffv is nil");
// "ffv is nil" is not printed
这是正确的,释放对象不会将指针设置为nil,即使它当时被解除分配。好的做法是在释放指针后将其设置为nil。
您可以正确地说,在您发布它之后,它没有被解除分配,因为视图仍然保留在它上面。但你不应该这么想。如果您想使用该对象并且希望它处于活动状态,请保留它。不管还有谁在保留它。您的对象与其他对象无关。你想要它,就保留它。完成后,释放它并将指针设置为零。如果您不将其设置为nil,而其他人也发布了它,您将有一个指向已解除分配的对象的悬空指针,这将导致崩溃和许多不满
因此:
[ffv release]; // you can release it now since the view has ownership of ffv
ffv = nil; // you released it, so that means you don't want it anymore, so set the pointer to nil
如果你仍然想使用它,在完成之前不要释放它
1) 我的推论正确吗
你的推论是正确的。说明每个对象都有一个或多个所有者。您拥有使用以alloc
、new
、copy
或mutableCopy
开头的任何方法创建的任何对象。您还可以使用retain获得对象的所有权。处理完对象后,必须使用release
或autorelease
放弃所有权
释放对象不会更改引用该对象的任何变量的值。变量包含对象的内存地址,直到重新分配它为止,无论对象的保留计数是多少。即使对象的保留计数变为零,导致对象被解除分配,您的变量仍将指向该地址。如果您尝试在解除分配对象后访问该对象,您的应用程序通常会因EXC_BAD_访问而崩溃。这是一个常见的内存管理错误
2) 从中还可以推断出其他重要的东西吗
我什么都没想到
3) 仍然保留(使用)ffv和从ffv调用方法会导致哪些并发症?(我的意见是,这是可以的,因为视图将始终拥有ffv,并且在someo之前不会发布它。)
ffv = [[[FullFunctionView alloc] initWithFrame:self.view.bounds] autorelease];