【发布时间】:2014-01-12 07:44:39
【问题描述】:
我正在编写一个应用程序,用户应该能够单击按钮并切换视图。我创建了IBActions,将我的方法 switchSubView 加载到所需的视图上,但这样做时遇到了一些问题。我目前已经编写了方法来动画两个NSViews 之间的过渡,这些NSViews 通过Interface Builder 作为IBOutlets 连接。我可以使用这些方法在两个视图之间转换,但是当我尝试从初始视图切换到另一个视图,然后切换到另一个视图,然后再切换回来时,我得到EXC_BAD_ACCESS。我似乎无法调试问题。调试器显示两个NSView 对象以指向不同的内存位置。为了澄清,我想在应用程序执行期间重用视图。我不希望任何视图被释放。
代码如下:
- (void)switchSubViews:(NSView *)firstView withView:(NSView *)secondView {
[firstView setSubviews:[NSArray array]];
[self prepareViews:firstView];
[[firstView animator] addSubview:secondView];
}
/* Make a "move" animation effect. */
- (void)prepareViews:(NSView *)prepareView {
CATransition * transition = [CATransition animation];
[transition setType:kCATransitionPush];
[transition setSubtype:kCATransitionFromRight];
[prepareView setAnimations:[NSDictionary dictionaryWithObject:transition forKey:@"subviews"]];
[prepareView setWantsLayer:YES];
}
基本上,我会这样称呼它,给定 initialView 和 newView:
[self switchSubViews:initialView withView:newView];
谁能帮我调试一下?
谢谢。
更新:在注释掉 for 循环和 removeFromSuperview 代码进行调试后,我仍然收到错误的访问错误。视图的属性设置为@property (nonatomic, strong),那么视图不应该保留吗?如果没有,我如何在启用 ARC 的情况下明确保留我的 NSView?是否可以告诉 ARC 保留它,或者它已经保留了视图,因为它是用 @property(nonatomic, strong) 设置的?
第二次更新:我研究了一下,发现我可以通过创建一个指向对象的强指针来使 ARC 保留该对象。我通过创建实例变量进行了尝试:
@interface AppDelegate : NSObject <NSApplicationDelegate, NSWindowDelegate> {
/* Some instance variables here... */
__strong NSView * retainFirstView;
__strong NSView * retainSecondView;
}
@property (nonatomic, strong) NSView * retainFirstView;
@property (nonatomic, strong) NSView * retainSecondView;
然后在.m文件中:
#import <Quartz/Quartz.h> /* Animation. */
#import "AppDelegate.h"
/* Some other imports necessary... */
@implementation AppDelegate
@synthesize retainFirstView;
@synthesize retainSecondView;
/* Some subview switching code... */
[self setRetainFirstView:firstView];
[self setRetainSecondView:secondView];
@end
但我仍然收到错误消息。似乎我正在换出的视图一直被解除分配。我在这方面花费了大量时间,但无法摆脱错误。任何帮助,将不胜感激。如果这不是保留视图的正确方法,请告诉我。
更新 3:为了测试,我暂时禁用了 ARC,并在调用 setSubviews 或 addSubview 之前执行了此操作:
[firstView retain];
[secondView retain];
它仍然失败。我很困惑,因为我不再看到可能导致释放的原因。
更新 4:我通过在 Xcode 中执行 Product -> Profile 检查了僵尸和发送到已释放对象的消息,令我惊讶的是,我没有收到任何通知。我很困惑为什么会发生这种情况。
【问题讨论】:
标签: objective-c macos cocoa automatic-ref-counting nsview