工程视图在drawRect Objective-c OSX中无限地实例化新的子视图

工程视图在drawRect Objective-c OSX中无限地实例化新的子视图,objective-c,macos,core-graphics,drawrect,quartz-2d,Objective C,Macos,Core Graphics,Drawrect,Quartz 2d,我在画一棵非结构化的二叉树。我现在遇到的问题是,当我构建应用程序时,它会进入一个无限循环,始终创建新的nodeView对象 我不熟悉程序绘图。我知道我犯了一些很明显的基本错误。在不经常重新实例化这些视图的情况下,绘制NSView树的最佳方法是什么 理想情况下,我希望能够拖放NSView节点。我可以稍后再弄明白,这些信息只是为了以防万一 - (void)drawRect:(NSRect)dirtyRect { if (!hasSetUp) [self setUp]; [super

我在画一棵非结构化的二叉树。我现在遇到的问题是,当我构建应用程序时,它会进入一个无限循环,始终创建新的nodeView对象

我不熟悉程序绘图。我知道我犯了一些很明显的基本错误。在不经常重新实例化这些视图的情况下,绘制NSView树的最佳方法是什么

理想情况下,我希望能够拖放NSView节点。我可以稍后再弄明白,这些信息只是为了以防万一

- (void)drawRect:(NSRect)dirtyRect {
    if (!hasSetUp) [self setUp];
    [super drawRect:dirtyRect];

    DTNodeView *nodeView = [[DTNodeView alloc] initWithFrame:NSMakeRect(200, 200, 100, 100)];
    //[self addSubview:nodeView];


    [[NSColor yellowColor] set];
    NSRectFill([self frame]);

    //NSLog(@"Subviews are: %@", [self.window.contentView subviews]);

    NSLog(@"Left tree height: %i", leftTree.treeHeight);

    double deltaY = (self.window.frame.size.height / 2) / ([leftTree treeHeight] + 1);
    [self drawSubtreeFromNode:[leftTree root] yValue:self.window.frame.size.height - 100 yDecrement:deltaY leftBound:0 rightBound:self.window.frame.size.width / 2];

    // Drawing code here.
}

-(void)drawSubtreeFromNode:(DTNode *)node yValue:(double)y yDecrement:(double)deltaY leftBound:(double)left rightBound:(double)right {

    double x = (left + right) / 2; // Draw the node in between the parents

    DTNodeView *selfRoot = [[DTNodeView alloc] initWithFrame:NSMakeRect(x, y, 100, 50) andNode:node];
    [self addSubview:selfRoot];

    if ([node hasLeft]) {
        double y2 = (y - deltaY);
        double x2 = (left + ((left + right)/2))/2;


        [[NSColor redColor] set];
        NSBezierPath *line = [[NSBezierPath alloc] init];
        [line setLineWidth:2];
        [line moveToPoint:NSMakePoint(x, y)];
        [line lineToPoint:NSMakePoint(x2, y2)];
        [line stroke];

        //drawSubtree(node.getLeft(), y-yDecrement, yDecrement, left, ((left + right)/2));
        [self drawSubtreeFromNode:[node left] yValue:(y - deltaY) yDecrement:deltaY leftBound:left rightBound:((left + right) / 2)];

    }

    if ([node hasRight]) {
        double x2 = (right + ((left + right)/2))/2;
        double y2 = (y - deltaY);

        [[NSColor redColor] set];
        NSBezierPath *line = [[NSBezierPath alloc] init];
        [line setLineWidth:2];
        [line moveToPoint:NSMakePoint(x, y)];
        [line lineToPoint:NSMakePoint(x2, y2)];
        [line stroke];


        //drawSubtree(node.getRight(), y-yDecrement, yDecrement, ((left + right)/2), right);
        [self drawSubtreeFromNode:[node right] yValue:(y - deltaY) yDecrement:deltaY leftBound:((left + right) / 2) rightBound:right];

    }

}

在drawRect方法中,您应该绘制而不绘制其他内容。它不是创建视图并将其添加到superview的地方。很明显,添加子视图意味着需要重新绘制视图,然后将创建新的子视图等。

因此,我是否应该创建一个方法来实例化子视图,然后在draw方法中调用addSubview:在所有这些子视图上?是的,您需要预先创建绘图所需的所有对象(init或LayoutSubView,或您喜欢的任何视图)以使图形尽可能具有性能。