我有一个基于文档的应用程序,它使用结构作为其主要数据/模型。由于模型是它(的子类)的属性,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) 我正在使用 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 不想让我摆弄那个参数。
如何确保在调整大小期间始终正确重绘内容?
我有一个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 的方式相同?
我想为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类,并且不调用"基本方法".我怎样才能弄清楚哪些方法被认为是原始的?
我有一个基于文档的应用程序,其中NSSplitViewController作为主窗口的内容视图控制器。左窗格包含带有控制器的自定义视图,该视图实现了一些菜单命令。
右窗格包含带有控制器的标准NSTableView。当应用程序启动时,菜单命令会按预期工作,但是一旦选择了右表视图中的任何内容,菜单命令就会被禁用。
如何确保左窗格的视图控制器保留在第一响应者链中?
我尝试将菜单命令直接连接到正确的视图控制器,但是IB不允许连接到情节提要中的另一个场景。我只能连接到同一场景中的对象。
问候,
雷姆科·波尔斯特拉
为什么下面的曲面细分控制着色器会使大多数三角形消失?
#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 语句,我相信这有助于着色器的并行执行。当然,我在片段中省略了顶点计算。
macos ×3
swift ×2
cocoa ×1
glsl ×1
metal ×1
nstableview ×1
objective-c ×1
opengl ×1
tessellation ×1