随着Observers正式从Rails 4.0中删除,我很好奇其他开发人员在他们的位置使用了什么.(除了使用提取的宝石.)虽然Observers肯定被滥用并且有时很容易变得笨拙,但是在缓存清除之外有许多用例,它们是有益的.
例如,需要跟踪模型更改的应用程序.观察者可以轻松地观察模型A的变化,并在数据库中记录模型B的变化.如果你想观察几个模型的变化,那么一个观察者就可以处理它.
在Rails 4中,我很好奇其他开发人员使用什么策略代替Observers来重新创建该功能.
就个人而言,我倾向于某种"胖控制器"实现,在每个模型控制器的创建/更新/删除方法中跟踪这些更改.虽然它稍微膨胀了每个控制器的行为,但它确实有助于可读性和理解,因为所有代码都在一个地方.缺点是现在的代码非常相似,分散在几个控制器中.将该代码提取到帮助器方法是一种选择,但您仍然可以调用遍布各处的方法.不是世界末日,也不是"精瘦控制者"的精神.
ActiveRecord回调是另一种可能的选择,虽然我个人并不喜欢,因为在我看来它往往会将两个不同的模型紧密地结合在一起.
所以在Rails 4中,no-Observers世界,如果你必须在创建/更新/销毁另一条记录之后创建一条新记录,你会使用什么样的设计模式?胖控制器,ActiveRecord回调,还是完全不同的东西?
谢谢.
当使用[NSString boundingRectWithSize:options:attributes]返回的rect的大小比我期望的某些字符串高.返回的高度似乎表示具有给定属性的字符串的最大可能高度,而不是字符串本身的高度.
假设相同的属性和选项,字符串" cars" 返回的高度与字符串" " 返回的高度相同ÉTAS-UNIS(注意E上的重音).
我本来希望boundingRectWithSize只考虑给定字符串中的字符,在我看来,它会为字符串" cars" 返回一个较短的高度.
在附带的截图中,我填写了返回的矩形,boundingRectWithSize并用红色概述了我认为边界矩形应该是什么.矩形的宽度与我预期的差不多,但高度比我预期的要高得多.这是为什么?

示例代码:
NSRect boundingRect = NSZeroRect;
NSSize constraintSize = NSMakeSize(CGFLOAT_MAX, 0);
NSString *lowercaseString = @"cars";
NSString *uppercaseString = @"ÉTAS-UNIS";
NSString *capitalizedString = @"Japan";
NSFont *drawingFont = [NSFont fontWithName:@"Georgia" size:24.0];
NSDictionary *attributes = @{NSFontAttributeName : drawingFont, NSForegroundColorAttributeName : [NSColor blackColor]};
boundingRect = [lowercaseString boundingRectWithSize:constraintSize options:0 attributes:attributes];
NSLog(@"Lowercase rect: %@", NSStringFromRect(boundingRect));
boundingRect = [uppercaseString boundingRectWithSize:constraintSize options:0 attributes:attributes];
NSLog(@"Uppercase rect: %@", NSStringFromRect(boundingRect));
boundingRect …Run Code Online (Sandbox Code Playgroud) 使用Vibrant Dark(NSAppearanceNameVibrantDark)或Vibrant Light(NSAppearanceNameVibrantLight)模式的正确方法是NSWindow什么?
我正在构建一个应用程序,并希望提供新的Vibrant Dark外观作为主应用程序的选项NSWindow.窗口本身是一个非常直接的窗口,NSToolbar顶部和滚动视图作为主要内容区域.
苹果公司提供了大量关于使用新的活力外观和a的信息NSVisualEffectsView,但我正在寻找关于如何使用这些外观的澄清NSWindow.
在NSAppearance.h头文件中,有一条注释声明应该只在一个上设置生动的外观NSVisualEffectsView.没有提到它得到支持NSWindow.
WWDC视频谈论确保您使用图层支持的视图,并且在使用新的充满活力的外观时允许您的子视图充满活力,但同样,没有提及使用它们NSWindow.
VisualEffectsPlayground示例代码确实有一个类似Facetime的应用程序的示例,它使用暗光振动模式,但它没有工具栏,它使用全内容掩码.
根据该信息,我在我的NSWindowController's windowDidLoad方法中执行以下操作:
[self.window.contentView setWantsLayer:YES];
self.window.appearance = [NSAppearance appearanceNamed:NSAppearanceNameVibrantDark];
Run Code Online (Sandbox Code Playgroud)
而且,果然,我得到一个NSToolbar带有黑色窗口标题栏的黑色.因此看起来它正常工作,但是当我的滚动视图滚动其内容(图像的缩略图)时NSToolbar,窗口标题栏下的标准半透明要么不存在,要么随机出现.似乎没有任何模式.有时当我滚动滚动视图时,内容在工具栏和标题栏下以"模糊"状态显示.其他时候滚动时,工具栏和标题栏只是一个不透明的黑色.(标题栏和工具栏仍然绘制其标题和按钮.)
当我没有为窗口的内容视图请求图层时,我得到的是更多的灰色标题栏和窗口标题,而不是"纯"的黑色标题栏.(我的scrollview的背景颜色可以是白色,深灰色或黑色.)
任何帮助或澄清如何正确配置NSWindow(包含NSToolbar和一个NSScollView)使用新的活力外观将非常感激.
我想尽可能高效地从潜在的数千个文件中读取一些元数据数据(例如:EXIF数据),而不会影响用户体验.我很感兴趣,如果有人对如何使用常规GCD队列,dispatch_io频道甚至其他实现方式进行最佳解决方案有任何想法.
这个非常简单我只能使用如下内容:
for (NSURL *URL in URLS) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
// Read metadata information from file.
CGImageSourceCopyProperties(...);
});
}
Run Code Online (Sandbox Code Playgroud)
我认为(并且经历过)这个实现的问题是,GCD不知道块中的操作是否与I/O相关,因此它将数十个这些块提交给全局队列进行处理,而后者又进行了饱和处理. I/O. 系统最终会恢复,但如果我正在阅读数千或数万个文件,那么I/O会受到影响.
这个看起来像是一个很好的竞争者,但实际上我使用常规GCD队列时性能更差.那可能是我的实施.
dispatch_queue_t intakeQueue = dispatch_queue_create("someName"), NULL);
for (NSURL *URL in URLS) {
const char *path = URL.path.UTF8String;
dispatch_io_t intakeChannel = dispatch_io_create_with_path(DISPATCH_IO_RANDOM, path, O_RDONLY, 0, intakeQueue, NULL);
dispatch_io_set_high_water(intakeChannel, 256);
dispatch_io_set_low_water(intakeChannel, 0);
dispatch_io_handler_t readHandler = ^void(bool done, dispatch_data_t data, int error) {
// Read metadata information from file.
CGImageSourceCopyProperties(...);
// Error stuff...
};
dispatch_io_read(intakeChannel, 0, …Run Code Online (Sandbox Code Playgroud) 在 Apple 的 2019 年 WWDC 视频中Swift Combine in Practice,他们演示了使用debounce发布者来减慢消息速度。
return $username
.debounce(for: 0.5, scheduler: RunLoop.main)
.removeDuplicates()
.eraseToAnyPublisher()
Run Code Online (Sandbox Code Playgroud)
但是,每当我尝试以类似的方式使用它时,都会出现以下错误:
无法使用类型为“(for:Double,调度程序:RunLoop)”的参数列表调用“debounce”
该debounce()签名是:
public func debounce<S>(for dueTime: S.SchedulerTimeType.Stride,
scheduler: S,
options: S.SchedulerOptions? = nil) ->
Publishers.Debounce<Self, S> where S : Scheduler
Run Code Online (Sandbox Code Playgroud)
SchedulerTimeType.Stride 似乎可以用数字初始化,但它对我不起作用,或者我对 Swift 泛型缺乏经验。
调用它的正确方法是什么?
编辑
重复这个问题...
目前,搜索诸如“组合”之类的通用词相当具有挑战性......
macOS 10.15,Xcode 11
在 SwiftUI 中,您可以将 a 的实例Publisher直接用作@ObjectBinding属性还是必须将其包装在实现 的类中BindableObject?
let subject = PassthroughSubject<Void, Never>()
let view = ContentView(data:subject)
struct ContentView : View {
@ObjectBinding var data:AnyPublisher<Void, Never>
}
// When I want to refresh the view, I can just call:
subject.send(())
Run Code Online (Sandbox Code Playgroud)
这不能为我编译,只是挂起 Xcode 11 Beta 2。但是你应该被允许这样做吗?
有没有办法让MPMoviePlayerController(甚至像AVPlayer这样的低级别)从iTunes Store播放受保护的M4V文件?
在此处使用官方iTunes API:http: //www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html
我可以获得电影,电视节目和音乐视频的"previewURL".音乐视频似乎没有受到保护,但电影和电视节目却受到保护.
例如,这是披头士的音乐视频的预览URL(实际上是纪录片,但无论如何):http: //a809.v.phobos.apple.com/us/r1000/006/Video/72/fe/ 52/mzm.bxhrrlns..640x480.h264lc.upm4v
这是"辛普森一家"一集的预览网址:http: //a911.v.phobos.apple.com/us/r1000/017/Video/ec/cc/cf/mzi.mnuqbbcl..640x480.h264lc. d2.p.m4v
使用MPMoviePlayerController可以播放音乐视频,但是辛普森一家的视频根本不播放.(当与MPMoviePlayerViewController一起使用时,视图控制器以模态方式显示,然后在没有任何用户交互的情况下立即被解除.)
如果您在QuickTime Pro中查看这两个URL,唯一明显的区别是第二个URL被列为"受保护",这将导致人们假设MPMoviePlayerController无法播放受保护的内容,即使该内容直接来自苹果.
在文档中的"支持的格式"部分下,M4V没有具体列出,但肯定有效.我找不到任何引用受保护内容的文档.
如果有人知道如何在应用程序内或通过其他方式播放此内容,那只是好奇.(调用[UIApplication ... openURL]也不起作用,因为Mobile Safari也不会播放内容.)
这是在iOS 4.x.
谢谢.
当NSTextField的宽度发生变化时,如何让自动布局自动将NSTextField包装到多行?
我有许多NSTextFields在检查器窗格中显示静态文本(即:标签).当用户调整检查器窗格的大小时,如果需要,我希望右侧标签能够回流到多行.
(Finder的"获取信息"面板执行此操作.)
但是我无法弄清楚自动布局约束的正确组合以允许这种行为.在所有情况下,右侧的NSTextFields拒绝换行.(除非我明确添加允许它的高度约束.)
视图层次结构使得每个灰色条带是包含两个NSTextField的视图,左侧是属性名称,右侧是属性值.当用户调整检查器窗格的大小时,我希望属性值标签根据需要自动调整其高度.
现在的情况:

我希望发生什么:

(请注意,这种行为与我遇到的关于NSTextFields和自动布局的大多数Stack Overflow问题不同.这些问题希望文本字段在用户输入时增长.在这种情况下,文本是静态的,NSTextField配置为看起来像一个标签.)
更新1.0
考虑到@ hamstergene的建议,我将NSTextField子类化并制作了一个示例应用程序.在大多数情况下,它现在可以工作,但现在有一个小的布局问题,我怀疑这是因为NSTextField的框架与自动布局所期望的完全不同步.在下面的屏幕截图中,右侧标签都是垂直间隔的top约束.在调整窗口大小时,Where字段将正确调整大小并进行包装.但是,在Kind我再次调整窗口"一个像素"之前,文本字段不会被推下.
示例:如果我将窗口的大小调整为Where文本字段首次换行的正确宽度,那么我会在中间图像中得到结果.如果我再向窗口调整一个像素,则会Kind正确设置字段的垂直位置.
我怀疑这是因为自动布局正在通过,然后帧被明确设置.我想自动布局在那个传球上没有看到,但是在下一次传球时看到它,并相应地更新位置.
假设这是问题,我如何通知我正在进行的这些更改的自动布局,setFrameSize以便它可以再次运行布局.(而且,最重要的是,不要陷入layout-setFrameSize-layout-etc.的递归状态...)
解
我想出了一个解决方案,似乎与我希望的完全一致.取而代之的子类的NSTextField,我只是覆盖layout的superview的NSTextField问题.在内部layout,我设置preferredMaxLayoutWidth文本字段,然后触发布局传递.这似乎足以使它大部分工作,但它留下了布局短暂"错误"的恼人问题.(见上面的注释).
解决方案似乎是调用setNeedsDisplay然后一切正常工作.
- (void)layout {
NSTextField *textField = ...;
NSRect oldTextFieldFrame = textField.frame;
[textField setPreferredMaxLayoutWidth:NSWidth(self.bounds) - NSMinX(textField.frame) - 12.0];
[super layout];
NSRect newTextFieldFrame = textField.frame;
if (oldTextFieldFrame.size.height != newTextFieldFrame.size.height) {
[self setNeedsDisplay:YES];
}
}
Run Code Online (Sandbox Code Playgroud) AVPlayer有一个叫做的属性rate,用于控制播放速率.1.0是正常速度,而值2.0或5.0应分别以2x和5x回放.
每当我将播放速率值设置为高于1.0(比如说10.0)时,播放就会非常不稳定,并且看起来大量的帧会因为播放器无法跟上而丢失.
但是,QuickTime Player中的相同值(使用相同的电影)可以生成平滑的播放速率2x, 5x, 10x, 30x and 60x(由QuickTime播放器报告).
我创建了一个测试OS X应用程序,它只包含一个AVPlayerView和两个用于设置播放速率的按钮.1.0工作速度如预期的那样,但10.0产生的速度非常不稳定.
然而,AVPlayerView有一个奇怪的怪癖,如果你鼠标点击播放时间线寻找到另一个位置(当它以10x和波动的方式播放时),那么AVPlayerView将"修复"播放并且电影将以10x平稳播放.只需单击播放时间线即可.
有谁知道如何平稳播放1x以外的费率?这显然不是硬件问题或文件大小问题,因为QuickTime Player和AVPlayerView都可以做到这一点.
尝试
这个问题表明它可能是一个音频问题(事实上,QuickTime播放器和AVPlayerView在转发时都会使音频静音)但是我所有试图禁用所有音轨,静音所有音轨或改变音频音调算法的尝试似乎都没有做出改变.即使没有音频,播放仍然不稳定.
我也试过停止播放然后prerollAtRate:completionHandler用新的速率呼叫,但这也没有什么区别.
QuickTime Player和AVPlayerView正在做什么,可以以10倍,30倍甚至60倍的速度播放流畅的电影?
众所周知,更新用户界面AppKit需要UIKit在主线程中进行。Metal 在呈现时是否有相同的要求drawable?
在我一直在使用的层托管中NSView,我注意到我可以[CAMetalLayer nextDrawable]从dispatch_queue不是main_queue. 然后我可以像往常一样更新该可绘制的纹理并呈现它。
这似乎工作正常,但我发现这很可疑。除非我忽略了文档中的某些内容,否则我找不到任何提及 Metal 的主线程要求的内容(无论是支持还是反对)。
(我正在 macOS 10.13 上进行测试,但我假设 iOS 的主线程要求也是相同的......?)
cocoa ×5
appkit ×4
macos ×4
objective-c ×3
ios ×2
swift ×2
autolayout ×1
avfoundation ×1
avplayer ×1
cocoa-touch ×1
combine ×1
drm ×1
ios4 ×1
metal ×1
metalkit ×1
nsstring ×1
nswindow ×1
osx-yosemite ×1
swift5 ×1
swiftui ×1
uikit ×1