【问题标题】:What is the proper use of "presentModalViewController:animated:" and "dismissModalViewControllerAnimated:"?“presentModalViewController:animated:”和“dismissModalViewControllerAnimated:”的正确用法是什么?
【发布时间】:2012-10-04 22:37:23
【问题描述】:

我在对象分配和释放方面遇到问题。 我正在开发一些具有图像编辑功能的应用程序。 当用户点击选择图像时,会出现 UIImagePickerController,然后当用户从库中选择图像时,UIImagePickerController 会关闭,然后有一个方法:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    //some logic

    FilterViewController *filterViewController = [[FilterViewController alloc] initWithImage:imageToWorkWith
                                                                                    withDelegate:self];

        /* present image processing screen, then release it */
        [((UIViewController *)self.delegate) presentModalViewController:filterViewController animated:NO];            
        [filterViewController release];
}

然后出现FilterViewController - 图像编辑屏幕。点击“完成”按钮后,将调用下一个方法:

- (void)dismissWithDone {
    [self.filterViewDelegate doneImageEdittingWithImage:self.imageToWorkWithView.image];
}

调用:

#pragma mark - FilterViewDelegate

- (void)doneImageEdittingWithImage:(UIImage *)imageToSend {
    //some logic

    [((UIViewController *)self.delegate) dismissModalViewControllerAnimated:NO];
}

一切似乎都正常工作,但问题是 filterViewController 没有解除分配并保留在内存中。如果我将选择再次编辑一些照片,我的意思是如果创建 filterViewController 的方法将被再次调用,那么前一个实例将被释放并呈现新的实例,依此类推。 我认为当调用 [UIViewController setChildModalViewController:] 时, filterViewController 的前一个实例在设置新实例时被释放。 如果再添加一个版本:

[((UIViewController *)self.delegate) presentModalViewController:filterViewController animated:NO];            
[filterViewController release];
[filterViewController release];

然后它会在关闭后被释放,但在创建新实例时会是 bad_access,因为它会尝试释放被释放的实例。

我不明白的: 1. 为什么关闭filterViewController后,仍然有大于0的引用计数,导致没有dealloc? 2. 为什么再增加一个release时,childModalViewController中deallocated对象的引用依然存在?

【问题讨论】:

  • 确保你使用的代表有assign属性而不是retain属性。

标签: iphone objective-c ios cocoa uiviewcontroller


【解决方案1】:

我在这里遇到的所有麻烦的原因是,我没有将我在那个 UIViewController 中使用的某个类中的某个块的某些属性设置为零。例如:我在这个 UIViewController 中使用 GPUImage 框架,并且我正在设置块:

self.movieWriter.completionBlock = ^{
    //do something with self.* properties
    [self someMethod];
}

所以,在关闭 UIViewController 之前,我没有设置 nil 来清理这个块属性:

self.movieWriter.completionBlock = nil;

这就是原因,没有在 UIViewController 上调用 dealloc。

另外here是关于块的解释以及为什么我们需要将它们的属性设置为nil。

【讨论】:

    猜你喜欢
    • 2013-03-09
    • 2011-04-15
    • 1970-01-01
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多