我的环境是Yosemite 10.10.5,Xcode 7.2使用ARC。
在一个简单的测试程序中,我尝试了各种方法来拒绝一个NSViewController,所有这些方法都显示出内存处理方面的问题。
在我的主视图控制器中,我有以下代码。(通知片段是用来测试各种方法来解除所述控制器的。)
- (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内部,我有:
- (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:]的方法有关。
是否有其他必要的清理措施来防止这些泄漏(或者在非泄漏情况下内存膨胀)?
发布于 2016-02-25 01:06:45
呈现另一个视图控制器的视图控制器也负责删除它。因此,在FirstReplacement方法中,没有一个行是正确的。相反,您应该在FirstReplacement中创建一个委托,这样它就可以通知它的委托(主视图控制器)它应该被取消。
FirstReplacement.h
@class FirstReplacement;
@protocol FirstReplacementDelegate <NSObject>
- (void)firstReplacementShouldDismiss:(FirstReplacement *)controller;
@end
@interface FirstReplacement : NSViewController
@property (nonatomic, weak) id<FirstReplacementDelegate> delegate;
@endFirstReplacement.m
- (IBAction)dismiss:(id)sender {
[self.delegate firstReplacementShouldDismiss:self];
}然后在主视图控制器中:
- (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不是使用任何方法调用的,而是使用委托调用的。
https://stackoverflow.com/questions/35605738
复制相似问题