首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSViewController --清除内存

NSViewController --清除内存
EN

Stack Overflow用户
提问于 2016-02-24 15:05:41
回答 1查看 645关注 0票数 2

我的环境是Yosemite 10.10.5,Xcode 7.2使用ARC。

在一个简单的测试程序中,我尝试了各种方法来拒绝一个NSViewController,所有这些方法都显示出内存处理方面的问题。

在我的主视图控制器中,我有以下代码。(通知片段是用来测试各种方法来解除所述控制器的。)

代码语言:javascript
复制
- (IBAction)showFirstReplacement:(id)sender {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissWithNotification:) name:@"removeFirst" object:nil];
    NSStoryboard *sb = [self storyboard];
    FirstReplacement *controller = [sb instantiateControllerWithIdentifier:@"first_replacement"];
    [self presentViewControllerAsSheet:controller];
}

- (void)dismissWithNotification:(NSNotification *)notification {
    NSViewController *controller = [notification object];
    [self dismissViewController:controller];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

FirstReplacement内部,我有:

代码语言:javascript
复制
- (IBAction)dismiss:(id)sender {
    [self dismissViewController:self];
//  [[NSNotificationCenter defaultCenter] postNotificationName:@"removeFirst" object:self];
//  [[self presentingViewController] dismissViewController:self];
}

取消注释此方法中的三行中的任何一行都会产生正确的可视结果,但是.取决于我在dismiss:中启用的调用,在分析时得到不同的结果。使用self dismissViewController:,我看到没有泄漏,但FirstReplacement对象没有被释放。使用另外两种方法中的任何一种,都可以摆脱掉掉的FirstReplacement,但是每次一个视图控制器被关闭时,都会泄漏一个16字节的malloc块和一个NSMutableArray

据仪器公司称,泄漏与一种名为[NSViewController _addPresentedViewController:]的方法有关。

是否有其他必要的清理措施来防止这些泄漏(或者在非泄漏情况下内存膨胀)?

EN

回答 1

Stack Overflow用户

发布于 2016-02-25 01:06:45

呈现另一个视图控制器的视图控制器也负责删除它。因此,在FirstReplacement方法中,没有一个行是正确的。相反,您应该在FirstReplacement中创建一个委托,这样它就可以通知它的委托(主视图控制器)它应该被取消。

FirstReplacement.h

代码语言:javascript
复制
@class FirstReplacement;

@protocol FirstReplacementDelegate <NSObject>
- (void)firstReplacementShouldDismiss:(FirstReplacement *)controller;
@end

@interface FirstReplacement : NSViewController
@property (nonatomic, weak) id<FirstReplacementDelegate> delegate;
@end

FirstReplacement.m

代码语言:javascript
复制
- (IBAction)dismiss:(id)sender {
    [self.delegate firstReplacementShouldDismiss:self];
}

然后在主视图控制器中:

代码语言:javascript
复制
- (IBAction)showFirstReplacement:(id)sender {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissWithNotification:) name:@"removeFirst" object:nil];
    NSStoryboard *sb = [self storyboard];
    FirstReplacement *controller = [sb instantiateControllerWithIdentifier:@"first_replacement"];
    controller.delegate = self;
    [self presentViewControllerAsSheet:controller];
}

- (void)firstReplacementShouldDismiss:(FirstReplacement *)controller {
    [self dismissViewController:controller];
}

虽然似乎发布通知与委托相同,但事实并非如此。不同之处在于,当dismissWithNotification触发时,您仍然在执行FirstReplacement::fires中的代码。NSNotificationCenter::postNotificationName在所有观察者完成其选择器执行之前不会完成执行。因此,即使在主视图控制器中正在执行拒绝代码,它仍然是从from方法运行的。

如果仍然不确定,请重写FirstReplacement::dealloc以打印log语句。您将看到dealloc不是使用任何方法调用的,而是使用委托调用的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35605738

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档