代码之家  ›  专栏  ›  技术社区  ›  Mausimo

iPhone-内存管理问题

  •  1
  • Mausimo  · 技术社区  · 15 年前

    我正在检查我的代码,并试图掌握正确的内存管理。此代码:

    imageView = [[[UIImageView alloc] initWithImage:myImage] autorelease];
    

    导致我的应用程序崩溃。我在导航栏控制器中使用多个视图控制器。该应用程序运行良好:我可以从第一个视图控制器(TableView)中选择一个人,它会将我放到该人的照片列表中,然后我可以从该视图控制器(TableView)中选择一张照片,并移动到带有用于查看照片的滚动视图的最终视图。一旦我在导航栏上点击,就会加载上一个视图(tableview中的照片列表),但是在使用以下代码取消选择行之前,应用程序会崩溃:

    - (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];  
        if(RowSelected != nil)
        {
            [MainTableView deselectRowAtIndexPath:RowSelected animated:YES];
        }
    }
    

    当用户单击行时,将存储选定行。

    如果我将代码保留为:

    imageView = [[UIImageView alloc] initWithImage:myImage];
    

    应用程序运行良好。我做错什么了吗?我不需要自动释放这个吗?

    3 回复  |  直到 15 年前
        1
  •  3
  •   Noah Witherspoon    15 年前

    确保在视图控制器的 -loadView -viewDidLoad ,不在其初始值设定项中。当控制器的视图离开屏幕时,通常会被释放,从而释放其子视图;因此,您不应该期望引用 imageView 保持有效。如果您出于某种原因需要图像视图保留在内存中,即使视图控制器处于屏幕外,也可以不调用 -autorelease 当你创建它的时候;只要确保调用 [imageView release]; 在你的控制器里 -dealloc .

        2
  •  0
  •   progrmr    15 年前

    当您将imageview标记为autorelease时,它将在下次通过run循环释放。如果仍在引用或使用imageview,则使用指向已释放堆空间的指针。堆空间将被覆盖(迟早),您将引用垃圾并崩溃。

    我认为正确的解决方案是imageview应该是一个被保留的属性,但是我不确定您对imageview做了什么,所以我在这里只是猜测。如果将imageview添加到视图控制器视图中,它将保留在子视图数组中。总之,它必须由使用它的人保留。

    您将使imageview成为.h文件中的保留属性:

    @property (nonatomic, retain) UIImageView* imageView;
    

    然后使用setter,它将保留它:

    UIImageView* tmpIV = [[UIImageView alloc] initWithImage:myImage];
    self.imageView = tmpIV;   // copy the pointer, setter will retain it
    [tmpIV release];          // release the original alloc
    

    不要忘记@synthesis来创建setter/getter。

        3
  •  0
  •   Mausimo    15 年前

    ImageView在My.h中。我在My-ViewDidLoad中使用这一行,一旦它离开屏幕,我就不需要该视图:

    imageView = [[[UIImageView alloc] initWithImage:myImage] autorelease];
    

    我认为我正在做的是将分配的uiimageview分配给我的imageview,如果我自动释放,那么重新登录将被关闭,因为我的-dealloc释放了?(如果我错了,请纠正我)

    如果我检查我的-解除锁定:

    - (void)dealloc {
    NSLog(@"%i", [photo retainCount]);
    [photo release];
    
    NSLog(@"%i", [imageView retainCount]);
    [imageView release];    
    [super dealloc];
    

    }

    在nslog中,imageview的retain count是1,我猜当它执行[super dealloc]时,它会在imageview已经因为[imageview release]而为0时,尝试从imageview中再获取1个retain count?

    如果我有电话: imageView = [[UIImageView alloc] initWithImage:myImage]; 那么保留计数在nslog中是2,1进入[super dealloc]

    如果我使用 KK6YB 的方法,然后应用程序工作没有问题,但是我认为我不应该这样做,因为使用他的方法,如果我在dealloc中检查我的retain count,它在nslog中也是2…

    我很困惑,昨天我读了很多关于内存管理的文章,以便更好地掌握一些事情,因为我正在释放-dealloc中的imageview,我相信我不需要在那行上自动释放它?

    有没有办法检查xcode中的内存泄漏?

    谢谢!