gpt4 book ai didi

crash - NSTableView 在添加到 SplitView 的自定义 View 中崩溃

转载 作者:行者123 更新时间:2023-12-03 17:33:13 25 4
gpt4 key购买 nike

我的意图是为带有两个 Pane 的 NSSplitView 提供 2 个单独的 View Controller 。在左 Pane 中,我想要一个表格 View ,但它崩溃了。这是场景:

我有一个带有 MainMenu.xib、AppDelegate.h/m 的简单项目。在这个项目中,我添加了一个 LeftPaneViewController.h/.m/.xib。

在 MainMenu.xib 中,我将 NSSplitView 添加到默认 View 。

在 AppDelegate.h 中:

@property (weak) IBOutlet NSSplitView *splitView;

在 AppDelegate.m 中:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
LeftPaneViewController *lpvc = [[LeftPaneViewController alloc] initWithNibName:@"LeftPaneViewController" bundle:nil];
[self.splitView replaceSubview:[[self.splitView subviews] objectAtIndex:0] with:lpvc.view];
}

我将 MainMenu.xib 中的 NSSplitView 连接到 AppDelegate 中的 splitView。

当我运行它时,它工作正常,但当然还没有什么可看的。

在 LeftPaneViewController.xib 中,我将 NSTableView 添加到默认自定义 View 。我删除了其中一列(列表中的底部)。

在 LeftPaneViewController.h 中:
@interface LeftPaneViewController : NSViewController <NSTableViewDelegate, NSTableViewDataSource>

@property (weak) IBOutlet NSTableView *tableView;
@property (nonatomic, retain) NSMutableArray *tableDataSource;

在 LeftPaneViewController.m 中:
#import "LeftPaneViewController.h"

@interface LeftPaneViewController ()

@end

@implementation LeftPaneViewController

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

- (void)awakeFromNib
{
self.tableDataSource = [[NSMutableArray alloc] initWithObjects:@"Row1", @"Row2", nil];
[self.tableView setNeedsDisplay];


}

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
// This is a defensive move
// There are cases where the nib containing the NSTableView can be loaded before the data is populated
// by ensuring the count value is 0 and checking to see if the namesArray is not nil, the app
// is protecting itself agains that situation
NSInteger count=0;
if (self.tableDataSource)
count=[self.tableDataSource count];
return count;
}


- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {

// Get an existing cell with the MyView identifier if it exists
NSTextField *result = [tableView makeViewWithIdentifier:@"LeftPaneCell" owner:self];

// There is no existing cell to reuse so create a new one
if (result == nil) {

// Create the new NSTextField with a frame of the {0,0} with the width of the table.
// Note that the height of the frame is not really relevant, because the row height will modify the height.
NSTextField *textField;

textField = [[NSTextField alloc] initWithFrame:NSMakeRect(2, 456, 125, 20)];
[textField setStringValue:@"My Label"];
[textField setBezeled:NO];
[textField setDrawsBackground:NO];
[textField setEditable:NO];
[textField setSelectable:NO];
[self.view addSubview:textField];

// The identifier of the NSTextField instance is set to MyView.
// This allows the cell to be reused.
result.identifier = @"LeftPaneCell";
}

// result is now guaranteed to be valid, either as a reused cell
// or as a new cell, so set the stringValue of the cell to the
// nameArray value at row
result.stringValue = [self.tableDataSource objectAtIndex:row];

// Return the result
return result;

}


@end

在 LeftPaneViewController.xib 中,我 Hook TableView 数据源并委托(delegate)给“文件所有者”(当然是 LeftPaneViewController)。并将 tableView 引用 socket 连接到 LeftPaneViewController.h 中的 tableView。我检查了这些至少一千次;-)

然后当我运行时,我得到以下崩溃日志:
* thread #1: tid = 0x23427, 0x00007fff82893250 libobjc.A.dylib`objc_msgSend + 16, queue = 'com.apple.main-thread, stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x00007fff82893250 libobjc.A.dylib`objc_msgSend + 16
frame #1: 0x00007fff88f8d972 AppKit`-[NSTableRowData _addViewToRowView:atColumn:row:] + 324
frame #2: 0x00007fff88f8d63f AppKit`-[NSTableRowData _addViewsToRowView:atRow:] + 151
frame #3: 0x00007fff88f8bbd5 AppKit`-[NSTableRowData _addRowViewForVisibleRow:withPriorView:] + 415
frame #4: 0x00007fff88f8b95a AppKit`-[NSTableRowData _addRowViewForVisibleRow:withPriorRowIndex:inDictionary:withRowAnimation:] + 272
frame #5: 0x00007fff88f8ac29 AppKit`-[NSTableRowData _unsafeUpdateVisibleRowEntries] + 740
frame #6: 0x00007fff88f8a7c1 AppKit`-[NSTableRowData updateVisibleRowViews] + 119
frame #7: 0x00007fff88f625a7 AppKit`-[NSTableView layout] + 165
frame #8: 0x00007fff88f15e65 AppKit`-[NSView _layoutSubtreeHeedingRecursionGuard:] + 112
frame #9: 0x00007fff8d11b4a6 CoreFoundation`__NSArrayEnumerate + 582
frame #10: 0x00007fff88f15fc6 AppKit`-[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
frame #11: 0x00007fff8d11b4a6 CoreFoundation`__NSArrayEnumerate + 582
frame #12: 0x00007fff88f15fc6 AppKit`-[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
frame #13: 0x00007fff8d11b4a6 CoreFoundation`__NSArrayEnumerate + 582
frame #14: 0x00007fff88f15fc6 AppKit`-[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
frame #15: 0x00007fff8d11b4a6 CoreFoundation`__NSArrayEnumerate + 582
frame #16: 0x00007fff88f15fc6 AppKit`-[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
frame #17: 0x00007fff8d11b4a6 CoreFoundation`__NSArrayEnumerate + 582
frame #18: 0x00007fff88f15fc6 AppKit`-[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
frame #19: 0x00007fff8d11b4a6 CoreFoundation`__NSArrayEnumerate + 582
frame #20: 0x00007fff88f15fc6 AppKit`-[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
frame #21: 0x00007fff88f15cfe AppKit`-[NSView layoutSubtreeIfNeeded] + 615
frame #22: 0x00007fff88f114ac AppKit`-[NSWindow(NSConstraintBasedLayout) layoutIfNeeded] + 201
frame #23: 0x00007fff88e0b0a8 AppKit`_handleWindowNeedsDisplayOrLayoutOrUpdateConstraints + 446
frame #24: 0x00007fff893d6901 AppKit`__83-[NSWindow _postWindowNeedsDisplayOrLayoutOrUpdateConstraintsUnlessPostingDisabled]_block_invoke_01208 + 46
frame #25: 0x00007fff8d0e9417 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
frame #26: 0x00007fff8d0e9381 CoreFoundation`__CFRunLoopDoObservers + 369
frame #27: 0x00007fff8d0c47b8 CoreFoundation`__CFRunLoopRun + 728
frame #28: 0x00007fff8d0c40e2 CoreFoundation`CFRunLoopRunSpecific + 290
frame #29: 0x00007fff8c17aeb4 HIToolbox`RunCurrentEventLoopInMode + 209
frame #30: 0x00007fff8c17ab94 HIToolbox`ReceiveNextEventCommon + 166
frame #31: 0x00007fff8c17aae3 HIToolbox`BlockUntilNextEventMatchingListInMode + 62
frame #32: 0x00007fff88e08533 AppKit`_DPSNextEvent + 685
frame #33: 0x00007fff88e07df2 AppKit`-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 128
frame #34: 0x00007fff88dff1a3 AppKit`-[NSApplication run] + 517
frame #35: 0x00007fff88da3bd6 AppKit`NSApplicationMain + 869
frame #36: 0x0000000100001872 TableView_In_SplitView`main(argc=3, argv=0x00007fff5fbff7e8) + 34 at main.m:13
frame #37: 0x00007fff84d4d7e1 libdyld.dylib`start + 1

通过断点,我确定在 LeftPaneViewController.m 中调用 numberOfRowsInTableView 并返回 2,但未调用 viewForTableColumn。

TableView 是基于单元格的,所以我确实希望调用 viewForTableColumn。

如果我只是将 NSTableView 添加到 MainMenu.xib 中的 SplitView 并将相同的代码传输到 AppDelegate.h/.m 中,它可以正常工作(当然也可以更改 Hook )。也就是说,它不会崩溃,并且会同时调用 numberOfRowsInTableView 和 viewForTableColumn。

那么我没有做什么导致崩溃?

最佳答案

好的,找到答案了。由于 AppDelegate.m 中的 LeftPaneViewController 变量 (lpvc) 是本地的,因此它在 replaceSubview 调用之后被释放。因此,在 AppDelegate.h 中将其添加为 (nonatomic, retain) 修复了崩溃。打开僵尸来寻找答案;-)。

关于crash - NSTableView 在添加到 SplitView 的自定义 View 中崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20660863/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com