Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c NSView setNeedDisplay:rect导致重绘的区域大于需要的区域_Objective C_Xcode_Macos_Cocoa - Fatal编程技术网

Objective c NSView setNeedDisplay:rect导致重绘的区域大于需要的区域

Objective c NSView setNeedDisplay:rect导致重绘的区域大于需要的区域,objective-c,xcode,macos,cocoa,Objective C,Xcode,Macos,Cocoa,我需要重新绘制一些NSView的一部分 - (IBAction)onUpdateView:(id)sender { NSRect updatedRect = ... // Redraw updated area only. [self.view setNeedsDisplayInRect:updatedRect]; } 当我使用这个简单明了的解决方案时,Quartz Debug会突出显示更大区域的重绘,直到视图的整个区域 我注意到,如果[NSView setNeedsDispl

我需要重新绘制一些NSView的一部分

- (IBAction)onUpdateView:(id)sender
{
    NSRect updatedRect = ... // Redraw updated area only.
    [self.view setNeedsDisplayInRect:updatedRect];
}
当我使用这个简单明了的解决方案时,Quartz Debug会突出显示更大区域的重绘,直到视图的整个区域

我注意到,如果[NSView setNeedsDisplayInRect]的调用被推迟到下一个运行循环周期,或者我只是执行[runloop runUntilDate:+0],问题就会消失:

- (IBAction)onUpdate:(id)sender
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self setNeedsDisplayInRect:updatedRect];
    });
}

但是,如果在mouseDown处理程序中调用setNeedsDisplayInRect,则它可以在没有所有这些黑客攻击的情况下工作:

-(void)mouseUp:(NSEvent*)event
{
    NSPoint p = [self convertPoint:[event locationInWindow] fromView:nil];

    int size = 100;
    [self setNeedsDisplayInRect:NSMakeRect(p.x-size/2, p.y-size/2, size, size)];
}
发生了什么事,该怎么办


解决此问题的独立Xcode项目如下:

是什么让您如此确信这是不受欢迎的行为?我在Quartz Debugger下看到的行为表明,当我点击更新按钮时,单击按钮的矩形和传递的dirtyRect的矩形的交点将闪烁。这是预期的,因为为了提高效率,系统将所有需要的绘图合并到运行循环的同一过程中(鼠标向上)

您的其他黑客方法绕过此行为,因为按钮的状态在一次(实际上是两次:鼠标向下和鼠标向上)过程中处理,视图的更新在后续过程中处理。如果您密切注意延迟的图形单击中的更新闪烁(按钮向下闪烁,再次向上闪烁,然后视图的脏区闪烁),则会验证这一点。单击视图本身不涉及任何其他内容(从技术上讲,它是非不透明的祖先),因此所有视图的脏rect的联合仅限于您请求的rect


我希望这会有所帮助。

该视图是否要重新绘制并使用自定义drawRect方法?如果是这样的话,你会把所有的东西都画进去吗?或者你会尊重直截了当,只重绘直截了当的东西吗?或者说,这一观点被删减了,并将其屏幕外的内容删去了?@HAS:当然,这是我第一次怀疑。附件项目中的drawRect方法字面上是“[NSBezierPath fillRect:dirtyRect];”您是否找到了比我在下面的回答和评论中提供的更好的解释?文字和透明度在绘图时会对性能产生重大影响。@JoshuaNozzi,没有任何解释-我们所拥有的只是未记录的奇怪行为和奇怪的解决方法。我在等待苹果DTS的意见。我是在12月3日发的,但还没有回复。这听起来很合理,但我不确定这种行为是否可取和正确。我尝试了另一个实验:我把一个文本标签放在主窗口的一个角落,然后开始在另一个角落画有趣的正方形。在本例中,QuartzDebug会闪烁整个2560x1600区域,而WindowsServer使用了大约50%的CPU:(图中显示了WindowsServer进程的CPU使用情况),这看起来确实很奇怪。如果覆盖自定义视图的-isOpaque以返回“是”,会发生什么?哇,这完全解决了附加xcodeproj:-)中的问题,来源:但我不清楚为什么系统决定重新绘制整个区域,即使下面没有视图。如果视图是不透明的,sysyem不必关心它背后的内容,也不必将一吨米的图层与漂亮的抗锯齿文本混合在一起。如果不是这样,可能还有很多其他图形层需要合成。您可能想设置StWavsStL:是的,在您的视图或其祖先之一,也可能考虑使用CATEXT层(在您的自定义视图的层次结构),而不是NSTEXFIELD字段。YMMV但我认为我们需要更多的细节来提供更优化的细节。我还怀疑正在进行的NSVisualEffect预计算Shennanigan可能与Yosemite beta Finder在图标查看模式下的滚动性能问题有关。我认为,一旦你将文本添加到混合中(在任何层上),系统提供的淘汰混合将变得更加昂贵。特别是当你考虑光/暗自动标签颜色的行为。如果可能的话,通过暗示不透明和使用层背景视图等来帮助解决这个问题。
-(void)mouseUp:(NSEvent*)event
{
    NSPoint p = [self convertPoint:[event locationInWindow] fromView:nil];

    int size = 100;
    [self setNeedsDisplayInRect:NSMakeRect(p.x-size/2, p.y-size/2, size, size)];
}