当前位置: 首页 > 面试题库 >

铸造瓶盖/块

艾和通
2023-03-14
问题内容

在Objective-C中,我经常绕过块。我经常使用它们来实现有助于避免将内容存储到实例变量中的模式,从而避免线程/定时问题。

例如,我将它们分配给过CAAnimation孔,-[CAAnimation setValue:forKey:]以便在动画结束时执行该块。(Objective-C可以将块视为对象;您也可以这样做[someBlock copy][someBlock release]。)

但是,尝试在Swift和Objective-C中同时使用这些模式似乎很困难。( 编辑:
我们可以看到该语言仍在不断变化:已经对代码进行了修改,因此它可以在Xcode6-beta2上运行,而先前版本则在Xcode6-beta1上运行。)

例如,我无法转换AnyObject回阻止/关闭。以下从编译器产生错误:

override func animationDidStop(anim: CAAnimation!, finished flag: Bool)
{
    let completion : AnyObject! = anim.valueForKey("completionClosure")
    (completion as (@objc_block ()->Void))()
    // Cannot convert the expression's type 'Void' to type '@objc_block () -> Void'
}

我找到了一种解决方法,但恕我直言,这很丑陋:在我的桥接标题中,我有:

static inline id blockToObject(void(^block)())
{
    return block;
}

static inline void callBlockAsObject(id block)
{
    ((void(^)())block)();
}

现在我可以在Swift中做到这一点:

func someFunc(completion: (@objc_block ()->Void))
{
    let animation = CAKeyframeAnimation(keyPath: "position")
    animation.delegate = self
    animation.setValue(blockToObject(completion), forKey: "completionClosure")
    …
}

override func animationDidStop(anim: CAAnimation!, finished flag: Bool)
{
    let completion : AnyObject! = anim.valueForKey("completionClosure")
    callBlockAsObject(completion)
}

它可以工作,但是我需要为每个要使用的每种块类型添加一个新函数,并且我在围绕编译器乱搞,这也不是一件好事。

那么有没有办法以一种纯粹的Swift方式解决这个问题呢?


问题答案:

Block用函数类型参数化的泛型怎么样?

class Block<T> {
  let f : T
  init (_ f: T) { self.f = f }
}

分配其中之一;它是的子类型,AnyObject因此可以分配给字典和数组。这似乎不太麻烦,尤其是在 尾随闭包 语法中。正在使用:

  5> var b1 = Block<() -> ()> { print ("Blocked b1") }
b1: Block<() -> ()> = {
  f = ...
}
  6> b1.f()
Blocked b1

另一个Block推断类型的例子:

 11> var ar = [Block { (x:Int) in print ("Block: \(x)") }]
ar: [Block<(Int) -> ()>] = 1 value {
  [0] = {
    f = ...
  }
}
 12> ar[0].f(111)
Block: 111


 类似资料:
  • 我目前在辅导一个高中生AP Java,她问了我一个关于“双选”的问题。我以前从未听说过这个术语,但显然她的老师希望她在即将到来的期末考试中知道这个术语。 她的老师提供的例子是,如果你想将一个整数转换成一个字符串,你必须执行以下操作才能避免编译器错误: 问题是:你想在现实生活中什么时候这样做? 老师只提供了导致运行时错误的示例。此外,我从来不知道有一个术语,但这样做似乎是个坏主意,因为只有当两种类型

  • 在抽象工厂模式中,我使用泛型。我有一个扩展Serializable的BaseEntity接口,Employee类实现了BaseEntity。在抽象类中,我有一个getJavaObj方法 是一种方法,它接受并返回

  • 在最近的一个问题中,有人提到,当使用printf打印指针值时,调用方必须将指针强制转换为void*,如下所示: 为了我的生命,我不知道为什么。我发现这个问题,几乎是一样的。这个问题的答案是正确的——它解释了整数和指针的长度不一定相同。 当然,这是正确的,但是当我已经有了指针,就像上面的例子一样,为什么我要从转换到?什么时候int*与void*不同?事实上,什么时候生成的机器代码不同于简单的? 更新

  • 另外,每当调用paint方法并再次绘制相同的屏幕时,Java是否会进行任何优化?例如,如果您只在屏幕上移动一个元素,那么通常只需要更新该元素。似乎每次调用paint方法时,java都会重新绘制和处理整个屏幕。对我来说,这一切似乎都是不必要的处理密集。 示例代码:

  • 我知道这是一个关于云铸造的普遍问题,目前的回答令人失望,尽管我认为这不可能用于微型云铸造的实例,但我想问一问,只是为了确保。是否可以在Micro Cloud Foundry实例上配置外部域,而无需从cloudfoundry子域进行隧道操作?