Objective c ARC似乎正在释放我的NSViewController的视图

Objective c ARC似乎正在释放我的NSViewController的视图,objective-c,cocoa,automatic-ref-counting,Objective C,Cocoa,Automatic Ref Counting,我试图解决一个更大的问题,我发现ARC显然过早地将视图发布到我的NSViewController。我想:)所以我创建了一个简单的应用程序来重建这种情况 我有一个简单的应用程序。在主菜单.xib的窗口中,我将自定义视图连接到@property(strong)ibnsoutlet*视图在AppDelegate.h中声明 在AppDelegate.m中,我合成属性,然后调用以下内容: - (void)applicationDidFinishLaunching:(NSNotification *)aNo

我试图解决一个更大的问题,我发现ARC显然过早地将视图发布到我的NSViewController。我想:)所以我创建了一个简单的应用程序来重建这种情况

我有一个简单的应用程序。在
主菜单.xib的窗口中,我将
自定义视图
连接到
@property(strong)ibnsoutlet*视图在AppDelegate.h中声明

AppDelegate.m
中,我合成属性,然后调用以下内容:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    TestViewController *tvc =  [[TestViewController alloc] initWithNibName:@"TestViewController" bundle:nil];
    [_theView addSubview:[tvc view]];
}  
#   Address Category    Event Type  RefCt   Timestamp   Size    Responsible Library Responsible Caller
0   0x7f97a3047560  TestViewController  Malloc  1   00:00.652.631   128 TestARC -[AppDelegate applicationDidFinishLaunching:]
1   0x7f97a3047560  TestViewController  Retain  2   00:00.653.088   0   TestARC -[TestViewController initWithNibName:bundle:]
2   0x7f97a3047560  TestViewController  Release 1   00:00.653.089   0   TestARC -[TestViewController initWithNibName:bundle:]
3   0x7f97a3047560  TestViewController  Retain  2   00:00.653.912   0   AppKit  -[NSNib instantiateNibWithOwner:topLevelObjects:]
4   0x7f97a3047560  TestViewController  Release 1   00:00.658.831   0   AppKit  -[NSNib instantiateNibWithOwner:topLevelObjects:]
5   0x7f97a3047560  TestViewController  Release 0   00:00.662.377   0   Foundation  -[NSNotificationCenter postNotificationName:object:userInfo:]
6   0x7f97a3047560  TestViewController  Zombie  -1  00:01.951.377   0   AppKit  -[NSApplication sendAction:to:from:]
TestViewController
显示在
自定义视图中
-没问题。它包含一个按钮。它连接到一个名为
-(IBAction)btnPressed:(id)sender
的方法和一个NSTextView,该NSTextView也连接为
IBOutlet

TestViewController.h
中,我声明:

@property (nonatomic, strong) IBOutlet NSTextField *textField;
@property (nonatomic, strong) NSString *theString;

-(IBAction)btnPressed:(id)sender;
TestViewController.m
I中

@synthesize theString = _theString;
@synthesize textField = _textField;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Initialization code here.
        _theString = @"Hello World";
    }

    return self;
}

-(IBAction)btnPressed:(id)sender
{
    [_textField setStringValue:_theString];
}
当我运行应用程序并按下按钮时,它崩溃了。如果我检查它是否有僵尸,我会收到以下信息:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    TestViewController *tvc =  [[TestViewController alloc] initWithNibName:@"TestViewController" bundle:nil];
    [_theView addSubview:[tvc view]];
}  
#   Address Category    Event Type  RefCt   Timestamp   Size    Responsible Library Responsible Caller
0   0x7f97a3047560  TestViewController  Malloc  1   00:00.652.631   128 TestARC -[AppDelegate applicationDidFinishLaunching:]
1   0x7f97a3047560  TestViewController  Retain  2   00:00.653.088   0   TestARC -[TestViewController initWithNibName:bundle:]
2   0x7f97a3047560  TestViewController  Release 1   00:00.653.089   0   TestARC -[TestViewController initWithNibName:bundle:]
3   0x7f97a3047560  TestViewController  Retain  2   00:00.653.912   0   AppKit  -[NSNib instantiateNibWithOwner:topLevelObjects:]
4   0x7f97a3047560  TestViewController  Release 1   00:00.658.831   0   AppKit  -[NSNib instantiateNibWithOwner:topLevelObjects:]
5   0x7f97a3047560  TestViewController  Release 0   00:00.662.377   0   Foundation  -[NSNotificationCenter postNotificationName:object:userInfo:]
6   0x7f97a3047560  TestViewController  Zombie  -1  00:01.951.377   0   AppKit  -[NSApplication sendAction:to:from:]
我做错了什么?
谢谢添加一个属性来保存视图控制器。在分配控制器的方法结束后,控制器当前没有任何东西可以使其保持活动状态

加:

修改:

self.tvc =  [[TestViewController alloc] initWithNibName:@"TestViewController" bundle:nil];
(我很好奇……如果您只想要它包含的视图,那么您认为创建视图控制器的意义是什么?)



关于一般方法,这似乎是更合适的行为,应该使用容器视图控制器来实现。该机制允许多个视图控制器以有组织的方式共享屏幕。

添加一个属性来保存视图控制器。在分配控制器的方法结束后,控制器当前没有任何东西可以使其保持活动状态

加:

修改:

self.tvc =  [[TestViewController alloc] initWithNibName:@"TestViewController" bundle:nil];
(我很好奇……如果您只想要它包含的视图,那么您认为创建视图控制器的意义是什么?)



关于一般方法,这似乎是更合适的行为,应该使用容器视图控制器来实现。该机制允许多个视图控制器以有组织的方式共享屏幕。

您需要添加ivar或属性来保存TextViewController。目前,对它的唯一引用是在
ApplicationIDFinishLaunching:
的末尾消失,这导致它被释放


这很糟糕,因为你的按钮需要控制器来控制按钮的按下。视图无法保持其控制器,因为这将导致一个保留周期。因此,如果您不希望按钮与解除分配的对象通信,那么您有责任保持控制器在附近

您需要添加ivar或属性来保存TextViewController。目前,对它的唯一引用是在
ApplicationIDFinishLaunching:
的末尾消失,这导致它被释放


这很糟糕,因为你的按钮需要控制器来控制按钮的按下。视图无法保持其控制器,因为这将导致一个保留周期。因此,如果您不希望按钮与解除分配的对象通信,那么您有责任保持控制器在附近

我使用ViewController将不同的视图(及其各自的方法)加载到主窗口中的自定义视图中。我想使用自定义视图作为可互换内容的“框架”。将AppDelegate.h更改为
@property(strong)IBOutlet TestViewController*theView
强制我删除
添加子视图
,对吗?但这不会将TestViewController的视图加载到自定义视图中……不,如果您希望设计以这种方式工作,请保留
addSubview
。正如我所说,
子视图
数组将负责保留它。在您最初的编码中,只有控制器的生命周期是一个问题。(不过,获得我认为您想要的更好的支持方式是创建一个容器视图控制器。使用该结构,可以定义用于维护父/子控制器关系的方法。)如果我保持addSubview行不变。然后,我得到一个错误,
No visible@interface for'TestViewController'声明选择器“addSubview”。
Sorry…我对您如何使用定义的属性做出了错误的假设。不要更改作为属性的内容,而是为控制器添加一个新属性,并在创建控制器时将其分配给该属性。我将更新我的答案。我的一般方法还有一个问题:在我的应用程序中,我有两个“部分”。每个部分都是彼此独立的,但是要相邻显示。这就是为什么我在主窗口上放置了两个自定义视图,并将它们分别连接到两个ViewController的视图上。我想在逻辑上和“物理上”分离代码。这是实现我尝试的操作的“错误”方式吗?我使用ViewController将不同的视图(及其各自的方法)加载到主窗口中的自定义视图中。我想使用自定义视图作为可互换内容的“框架”。将AppDelegate.h更改为
@property(strong)IBOutlet TestViewController*theView
强制我删除
添加子视图
,对吗?但这不会将TestViewController的视图加载到自定义视图中……不,如果您希望设计以这种方式工作,请保留
addSubview
。正如我所说,
子视图
数组将负责保留它。在您最初的编码中,只有控制器的生命周期是一个问题。(不过,获得我认为您想要的更好的支持方式是创建一个容器视图控制器。使用该结构,可以定义用于维护父/子控制器关系的方法。)如果我保持addSubview行不变。然后我得到一个错误,TestViewController的@interface不可见