Iphone Objective-C指针/内存管理问题

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在接口文件中声明

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的对象,您也会失去该对象的所有权,但是引用仍然保留

现在,我的问题是:

  • 我的推论正确吗
  • 从中还可以推断出其他重要的东西吗
  • 仍然保留(使用)ffv和从ffv调用方法会导致哪些并发症?(我的意见是,这是可以的,因为视图将始终拥有ffv,并且在有人调用viewDidUnload之前不会释放它。只要我不将ffv的引用传递给其他对象。)

  • 在保留计数变为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];