小编Rem*_*tra的帖子

使 Swift 并发中的任务串行运行

我有一个基于文档的应用程序,它使用结构作为其主要数据/模型。由于模型是它(的子类)的属性,NSDocument因此需要从主线程访问。到目前为止一切都很好。

但对数据的某些操作可能需要相当长的时间,我想为用户提供一个进度条。这就是问题开始的地方。特别是当用户从 GUI 快速连续启动两个操作时。

如果我同步(或以“正常”方式)在模型上运行操作,Task {}我会得到正确的串行行为,但主线程被阻止,因此我无法显示进度条。(选项A)

如果我在闭包中对模型运行操作,Task.detached {}我可以更新进度条,但根据模型上操作的运行时间,用户的第二个操作可能会在第一个操作之前完成,从而导致无效/意外状态模型的。这是由于await分离任务中需要的语句(我认为)。(选项B)。

所以我想要 a) 释放主线程来更新 GUI,b) 确保每个任务在另一个(排队的)任务开始之前运行完全完成。使用后台串行调度队列很有可能实现这一点,但我正在尝试切换到新的 Swift 并发系统,该系统也用于在访问模型之前执行任何准备工作。

我尝试使用全局参与者,因为这似乎是某种串行后台队列,但它也需要await语句。尽管模型中出现意外状态的可能性降低了,但这仍然是可能的。

我写了一些小代码来演示这个问题:

该模型:

struct Model {
    var doneA = false
    var doneB = false

    mutating func updateA() {
        Thread.sleep(forTimeInterval: 5)
        doneA = true
    }

    mutating func updateB() {
        Thread.sleep(forTimeInterval: 1)
        doneB = true
    }
}
Run Code Online (Sandbox Code Playgroud)

和文档(省略标准覆盖NSDocument):

@globalActor
struct ModelActor {
    actor ActorType { }

    static let shared: ActorType = ActorType()
}

class Document: …
Run Code Online (Sandbox Code Playgroud)

multithreading swift swift-concurrency

9
推荐指数
1
解决办法
3384
查看次数

在重绘之前调整 MTKView 的大小会缩放旧内容

我正在使用 MTKView 来绘制 Metal 内容。它的配置如下:

    mtkView = MTKView(frame: self.view.frame, device: device)
    mtkView.colorPixelFormat = .bgra8Unorm
    mtkView.delegate=self
    mtkView.sampleCount=4
    mtkView.isPaused=true
    mtkView.enableSetNeedsDisplay=true
Run Code Online (Sandbox Code Playgroud)

setFrameSize 被覆盖以触发重新显示。

每当视图调整大小时,它会在重绘所有内容之前缩放其旧内容。这给人一种颤抖的感觉。

我尝试将contentGravityMTKView 图层的属性设置为非调整大小的值,但这完全弄乱了内容的比例和位置。似乎 MTKView 不想让我摆弄那个参数。

如何确保在调整大小期间始终正确重绘内容?

macos core-animation metal

6
推荐指数
1
解决办法
2096
查看次数

使用 NSPasteboardItem 时,NSOutlineView 与安全范围 URL 的拖放失败

我有一个NSOutlineView包含 URL 作为项目的项目。这些 URL 属于安全范围,我希望它们能够被拖动到其他应用程序。

当我只返回 URL(项目)时,func outlineView(_ outlineView: NSOutlineView, pasteboardWriterForItem item: Any) -> NSPasteboardWriting?一切正常。但对于本地拖放(行重新排序),我需要其他信息,因此我创建一个NSPasteboardItem()来保存数据:

func outlineView(_ outlineView: NSOutlineView, pasteboardWriterForItem item: Any) -> NSPasteboardWriting? {
    let pasteboardItem=NSPasteboardItem()
    let itemURL = item as! NSURL

    //Write the absolute URL for d'n'd to other apps or windows
    pasteboardItem.setPropertyList(itemURL.pasteboardPropertyList(forType: .fileURL)!, forType: .fileURL)

    //Write data for local d'n'd.
    pasteboardItem.setPropertyList(<data>, forType: dragDropImageURLType)

    return pasteboardItem
}
Run Code Online (Sandbox Code Playgroud)

当我使用此代码时,出现以下错误,并且放置失败:

[一般] 风格 public.file-url 立即需要沙箱扩展数据,但无法获取。

如何确保写入 URL 的方式NSPasteboardItem与直接返回 URL 的方式相同?

macos nsoutlineview nstableview swift

5
推荐指数
0
解决办法
120
查看次数

子类化NSNumber

我想为NSNumber类添加一个属性,所以我必须将它子类化.文档说明我必须覆盖所有NSValue原语方法.由于NSValue文档没有说明哪些方法是原始方法,我认为这两个方法可能是实例化的原始方法:

– initWithBytes:objCType:  
+ valueWithBytes:objCType:
Run Code Online (Sandbox Code Playgroud)

所以我把我的课程改为:

@interface MultipleNumber : NSNumber {  
    NSNumber *_number;  
}  
@property (nonatomic, getter = isMultiple) BOOL multiple;  
@end

@implementation MultipleNumber  
@synthesize multiple=_multiple;  

-(id)initWithBytes:(const void *)value objCType:(const char *)type {  
    self = [super init];  
    if (self) {
        _number=[[NSNumber alloc] initWithBytes:value objCType:type];
    }
    return self;
}

+(NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type {
   return [[[MultipleNumber alloc] initWithBytes:value objCType:type] autorelease];
}

-(void)getValue:(void *)value { [_number getValue:value]; }

-(const char *)objCType { return [_number objCType]; }

@end
Run Code Online (Sandbox Code Playgroud)

但是当我调用[NSNumber numberWithBool:YES]时,我仍然得到一个_NSCFBoolean类,并且不调用"基本方法".我怎样才能弄清楚哪些方法被认为是原始的?

objective-c

4
推荐指数
3
解决办法
1504
查看次数

将两个NSSplitViewController的子控制器都保留在第一响应者链中

我有一个基于文档的应用程序,其中NSSplitViewController作为主窗口的内容视图控制器。左窗格包含带有控制器的自定义视图,该视图实现了一些菜单命令。

右窗格包含带有控制器的标准NSTableView。当应用程序启动时,菜单命令会按预期工作,但是一旦选择了右表视图中的任何内容,菜单命令就会被禁用。

如何确保左窗格的视图控制器保留在第一响应者链中?

我尝试将菜单命令直接连接到正确的视图控制器,但是IB不允许连接到情节提要中的另一个场景。我只能连接到同一场景中的对象。

问候,

雷姆科·波尔斯特拉

macos cocoa

4
推荐指数
1
解决办法
453
查看次数

GLSL 曲面细分控制着色器索引 gl_TessLevelOuter 和 gl_InitationID

为什么下面的曲面细分控制着色器会使大多数三角形消失?

#version 410

layout(vertices = 3) out;

void main(void) {
    gl_TessLevelInner[0]=1;
    gl_TessLevelOuter[gl_InvocationID]=gl_InvocationID+1;
    gl_TessLevelOuter[gl_InvocationID]=gl_InvocationID+1;
    gl_TessLevelOuter[gl_InvocationID]=gl_InvocationID+1;
}
Run Code Online (Sandbox Code Playgroud)

我输入三角形。当我用 0,1 和 2 索引 gl_TessLevelOuter 时,一切正常。在我看来,这个构造节省了我的 if 语句,我相信这有助于着色器的并行执行。当然,我在片段中省略了顶点计算。

opengl glsl tessellation

2
推荐指数
1
解决办法
2440
查看次数