跟我说,这需要一些解释.我有一个看起来像下面的功能.
上下文:"aProject"是名为LPProject的核心数据实体,其名为"memberFiles"的数组包含另一个名为LPFile的Core Data实体的实例.每个LPFile表示磁盘上的文件,我们要做的是打开每个文件并解析其文本,查找指向OTHER文件的@import语句.如果我们找到@import语句,我们希望找到它们指向的文件,然后通过向代表第一个文件的核心数据实体添加关系,将该文件"链接"到该文件.由于所有这些都需要一些时间在大文件上,我们将使用GCD在主线程上完成.
- (void) establishImportLinksForFilesInProject:(LPProject *)aProject {
dispatch_queue_t taskQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (LPFile *fileToCheck in aProject.memberFiles) {
if (//Some condition is met) {
dispatch_async(taskQ, ^{
// Here, we do the scanning for @import statements.
// When we find a valid one, we put the whole path to the imported file into an array called 'verifiedImports'.
// go back to the main thread and update the model (Core Data is not thread-safe.)
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"Got to main thread.");
for …
Run Code Online (Sandbox Code Playgroud) cocoa core-data objective-c grand-central-dispatch objective-c-blocks
在10.9上开发Cocoa应用程序时,我注意到如果我去~/Library/Preferences
删除我的应用程序的plist文件(重置它),在下一次构建和运行时,该应用程序的行为就好像plist文件从未删除了.
我花了很长时间来追踪这种情况发生的原因,我没有在SO上看到关于它的问题/答案,所以我正在写这个问题并自己回答它来帮助别人.
假设我有一个Core Data模型,其中包含一个名为"Animal" 的抽象实体.然后,我有许多其他实体从这个抽象实体继承:"狮子","狗","猫"等(我不是在开发一个动物园程序,但这个类比适用于我正在解释的问题!)
我想知道的是:我可以通过这样做一次取"所有动物":
NSFetchRequest *searchRequest = [[NSFetchRequest alloc] init];
[searchRequest setEntity:[NSEntityDescription entityForName:@"Animal" inManagedObjectContext:aContext]];
NSArray *matchedObjects = [aContext executeFetchRequest:searchRequest error:nil];
Run Code Online (Sandbox Code Playgroud)
我知道NSEntityDescription上有一些方法来确定一个实体是否继承自另一个实体.但是有没有一种快速的方法来获取特定(抽象)类型的所有实体 - 在这种情况下,"动物"?
如果上述方法无效,那么最有效的方法是什么?谢谢!
注意:这适用于OS X上的Cocoa应用程序,而不是iOS.
我有一个支持图层的NSButton(NSView的子类).我想要做的是使用Core Animation旋转该按钮.我正在使用以下代码来执行此操作:
CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
a.fromValue = [NSNumber numberWithFloat:0];
a.toValue = [NSNumber numberWithFloat:-M_PI*2];
[_refreshButton.layer setAnchorPoint:CGPointMake(0.5, 0.5)];
a.duration = 1.8; // seconds
a.repeatCount = HUGE_VAL;
[_refreshButton.layer addAnimation:a forKey:nil];
Run Code Online (Sandbox Code Playgroud)
这是有效的,除了它运行时,图层向下跳到左边,使其中心点位于NSView的原点,即(0,0)的左下角.然后该层围绕其中心旋转,但显然跳到左下角是不可接受的.
所以,经过多次阅读,我在10.8 API发行说明中找到了这一行:
On 10.8, AppKit will control the following properties on a CALayer
(both when "layer-hosted" or "layer-backed"): geometryFlipped, bounds,
frame (implied), position, anchorPoint, transform, shadow*, hidden,
filters, and compositingFilter. Use the appropriate NSView cover methods
to change these properties.
Run Code Online (Sandbox Code Playgroud)
这意味着AppKit在上面的代码中"忽略"我对-setAnchorPoint的调用,而是将该锚点设置为NSView的原点(0,0).
我的问题是:我该如何解决这个问题?什么是"适当的NSView封面方法"来设置图层的anchorPoint(我在NSView上找不到这样的方法).在一天结束时,我只是希望我的按钮无限期地围绕其中心点旋转.
背景:
下面的镜头是OS X Lion中的Mail.app.当源列表变得太长时,在源列表底部的按钮上方会出现一条漂亮的阴影线.滚动时,源列表会在该阴影线下移动.当您展开窗口以使源列表中的所有内容都适合而不滚动时,阴影线将消失.
问题:
如何使用Cocoa绘制这条阴影线?我知道NSShadow等等,但在我看来,这里发生的事情不仅仅是阴影.有一条线巧妙地淡化到点(就好像你在Photoshop中的每一端应用了渐变蒙版.)同样,阴影是椭圆形的,当你接近线的末端时逐渐变细.所以它不只是常规的NSShadow,是吗?(它绝对不是图像,因为当您扩展源视图的宽度时,它可以很好地缩放.)
关于如何绘制这种形状的任何提示都将非常感激.
对于坚持不懈的人来说,不,这并不违反NDA,因为Mail.app已被Apple公开展示.
我知道关于改变交替的行颜色还有其他问题.这很容易,这不是我想要做的.
我想在基于视图的NSTableView中绘制自定义交替颜色的行,这些行看起来像来自iTunes 11(行的顶部和底部的轻微边框,如此屏幕截图所示):
我知道我可以继承NSTableRowView并在那里进行自定义绘图.但是,这不是一个可接受的答案,因为自定义行仅用于表中包含数据的行.换句话说,如果表只有5行,那5行将使用我的自定义NSTableRowView类,但表中其余部分的剩余"行"(它们是空的)将使用标准的交替颜色.在这种情况下,前5行将显示挡板,其余的不显示.不好.
那么,我怎样才能破解NSTableView为填充行和空行绘制这些样式的交替行?
我有一个从状态栏运行的 Mac 应用程序。NSStatusItem
单击an 时,我显示 anNSWindow
而不是标准的NSMenu
。
在 Sonoma 之前,当NSStatusItem
单击 时,我使用了activate(ignoringOtherApps: true)
现已弃用的 API,以确保我的应用程序成为活动应用程序。这非常有效,所以苹果决定用核武器攻击它。
在 Sonoma 上,macOS 现在显示我的窗口,但不激活应用程序,这意味着用户必须单击 ,NSStatusItem
然后再次单击窗口,然后才能与我的 UI 交互。当用户单击窗口时,它还会产生非常不和谐的体验,因为活动应用程序最终会切换,但不是在用户期望的时候切换。我的窗口和之前活动的应用程序突然以不同的状态重绘。它很丑。
最糟糕的是,该问题仅在大约 85% 的时间内发生。15% 的情况下,系统会在显示 UI 时激活我的应用程序。我还无法确定它的模式,但这与 AppKit 发行说明相吻合,表明系统“可能”激活我的应用程序。(毫无疑问,如果一些愚蠢的、过度设计的、机器学习的官样文章认为这是值得做的。)
我如何告诉系统,当我的 NSStatusItem 被单击时,我的应用程序需要变为活动状态,因为 (A) 这是用户所期望的,(B) 替代方案看起来 macOS 已损坏?
我尝试过NSApplication.shared.setActivationPolicy()
使用两者.accessory
和甚至进行设置.regular
(即使添加了 Dock 图标和菜单栏),但问题仍然存在。
我正在使用Xcode的屏幕保护程序模板为OS X开发屏幕保护程序.通过检查系统屏幕保护程序的包内容,我发现屏幕保护程序的系统首选项列表中使用的缩略图来自屏幕保护程序包中的两个文件:
thumbnail.png (90x58)
thumbnail@2x.png (180x116)
Run Code Online (Sandbox Code Playgroud)
我创建了两个这些尺寸的图像,并将它们放在我的屏幕保护程序包中.但是,我的视网膜屏幕上的"系统偏好设置"面板似乎加载了非视网膜资产.以下是thumbnail@2x.png
图像的QuickLook预览旁边的"系统偏好设置"面板的屏幕截图:
我没有想法.任何人都知道可能导致这种情况的原因以及如何阻止它?我尝试过的事情:
thumbnail.png
- 结果相同.如果您检查系统屏幕保护程序的软件包,您会发现这两个缩略图文件不会在Finder中报告维度.如果你用Sketch打开它们,它们对于那个应用程序显示为90x58.(尽管Photoshop将@ 2x资产显示为180x116).来自系统屏幕保护程序的缩略图已经应用了光泽效果,而我的缩略图会自动获得该效果,即使图像资源不包含它也是如此.
我开始认为面板加载/绘制这些图像的方式有点可疑.也许有人知道我不知道的事情?
我的应用程序模型是一个对象树,其中每个对象代表给定起始文件夹下的磁盘上的文件系统项(文件夹或文件).
我会定期递归地从上到下遍历这个树,以便将它"同步"到文件系统的实际状态.也就是说,我访问模型中的每个对象并验证它所代表的文件/文件夹是否仍然存在于磁盘上的相同位置.
如果文件/文件夹已移动,我使用NSURL
书签来确定文件/文件夹的新位置,以便我可以更新我的模型的状态.(我NSURL
在第一次创建模型对象时创建了一个书签,然后将书签数据存储为对象的属性,以便我以后可以解决它.)
NSURL
书签根本不够高效.我的模型图有20,000个嵌套对象并不罕见.每个人都有一个书签.以下是我在分析性能时所看到的内容:
该recursivelyValidateExistingChildItemsOfParentItem:...
方法是我的模型树.所涉及的90%的时间只是解析书签(如果它们是陈旧的,则按Apple的文档中的描述重新创建它们).
这个应用程序需要将近2分钟才能完成步行.所以,我需要一个更快的NSURL
书签替代品.
扩展文件属性.我可以为磁盘上的每个文件添加一个UUID属性.我可以走在起始文件夹下面的实际文件系统,而不是走我的模型图.当我找到一个新文件时,我可以看到它是否具有UUID扩展属性.如果是这样,我可以在模型图中搜索具有该UUID的对象来处理移动/重定位的文件.这里的麻烦是许多东西破坏了扩展文件属性 - 它们不能保证坚持下去.
BDAlias
或NDAlias
.我曾经BDAlias
在迁移到NSURL
书签之前使用过,但这并不是特别高效.
我需要一个更快的替代NSURL
书签.但我仍然需要能够在我的应用程序的启动过程中跟踪文件,因此只需保持文件描述符打开或使用文件ID不起作用.
我不在乎我的低级水平; 我只需要表现.谢谢!
在使用 Swift 5.x 和 Xcode 14 构建的 Mac 应用程序中,我有一个控制器对象。该对象具有@Published
SwiftUI 视图观察到的多个属性,因此我将该对象放置在@MainActor
这样的位置:
@MainActor
final class AppController: NSObject, ObservableObject
{
@Published private(set) var foo: String = ""
@Published private(set) var bar: Int = 0
private func doStuff() {
...
}
}
Run Code Online (Sandbox Code Playgroud)
当Mac进入睡眠状态时,这个应用程序需要采取某些操作,因此我在方法中订阅了适当的通知init()
,但由于AppController
用 装饰@MainActor
,我收到此警告:
override init()
{
NSWorkspace.shared.notificationCenter.addObserver(forName: NSWorkspace.willSleepNotification, object: nil, queue: .main) { [weak self] note in
self?.doStuff() // "Call to main actor-isolated instance method 'doStuff()' in a synchronous nonisolated context; …
Run Code Online (Sandbox Code Playgroud) cocoa ×8
objective-c ×8
macos ×7
appkit ×2
core-data ×2
swift ×2
async-await ×1
macos-sonoma ×1
nsstatusitem ×1
nstableview ×1
nsurl ×1
performance ×1
plist ×1
screensaver ×1
xcode ×1