49

In tutorials it's written that functionally both are same even closure is more easier then block and its avoided the complexity of block and memory management, I've gone through many tutorials but except these I'm not getting the difference between swift's "closure" and Objective-C "block".

Cœur
  • 37,241
  • 25
  • 195
  • 267
Sujay
  • 2,510
  • 2
  • 27
  • 47
  • Marking an answer with a 'check mark' is expected StackOverflow behavior. If the provided answer does not meet your needs, then provide a comment to the answer. – GoZoner Oct 28 '14 at 01:22

3 Answers3

74

Excerpt From: Apple Inc. “Using Swift with Cocoa and Objective-C.” iBooks:

“Swift closures and Objective-C blocks are compatible, so you can pass Swift closures to Objective-C methods that expect blocks. Swift closures and functions have the same type, so you can even pass the name of a Swift function.

Closures have similar capture semantics as blocks but differ in one key way: Variables are mutable rather than copied. In other words, the behavior of __block in Objective-C is the default behavior for variables in Swift.”

Community
  • 1
  • 1
GoZoner
  • 67,920
  • 20
  • 95
  • 145
  • @GoZoner, can you please elaborate on the second statement with some example? – Ashok Apr 08 '20 at 11:19
  • > As an optimization, Swift may instead capture and store a copy of a value if that value isn’t mutated by a closure, and if the value isn’t mutated after the closure is created. https://docs.swift.org/swift-book/LanguageGuide/Closures.html – RY_ Zheng Apr 16 '21 at 04:44
5

Slight differences. One was mentioned; variables are captured as variables, not as values. Which can be either useful or a trap. Importantly you can define a capture list in a Swift closure, so if you include self.property in the capture list, then the value of that property is captured, and not self. That also simplifies capturing weak variables.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
2

To show an actual code example of the differences:

This does compile:

let x : @convention(swift) (inout Int) -> ()

This does not:

let y : @convention(block) (inout Int) -> ()

with the error (inout Int) -> () is not representable in Objective-C

Kametrixom
  • 14,673
  • 7
  • 45
  • 62
  • 1
    You cannot use inout because Objective-C calling convention doesn't have references and the conversion between a reference and a pointer is not implicit. It does have pointers though so you're going to have to use `UnsafePointer`.. Which makes the two signatures one in the same. – Brandon Jul 09 '16 at 22:00
  • @Brandon As previously said, if you're so sure that blocks and closures are the same, write the Swift devs that they should change the documentation of their language because you think it's wrong ;) – Kametrixom Jul 09 '16 at 22:22
  • @Brandon, 1 hour ago: "Blocks and Closures are the same" [source](http://stackoverflow.com/questions/38285689/in-swift-can-a-function-be-a-type/38285902#comment63991399_38285902); "[...] That doesn't mean it [a block] is not a closure." [source](http://stackoverflow.com/questions/38285689/in-swift-can-a-function-be-a-type/38285902#comment63991786_38285902). "Closures in Swift are similar to blocks in C and Objective-C", [Swift doc source](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-ID94) – Kametrixom Jul 09 '16 at 22:38
  • @Brandon Also on the same page: "Global and nested functions, as introduced in Functions, are actually special cases of closures." whereas you said: "Functions are not a special type of closure at all" [source](http://stackoverflow.com/questions/38285689/in-swift-can-a-function-be-a-type/38285902#comment63991444_38285902) – Kametrixom Jul 09 '16 at 22:39
  • Lol.. My statement merely re-enforces exactly what you just read from the Swift Docs. Not only are they similar, they are one in the same. They are both `NSBlock`. So again, tell me where I'm wrong. By definition a function and a closure is one in the same (wikipedia). However, not by assembly. They are NOT implemented the same. Closures are called via "Invoke". Functions are called directly by pushing the arguments in registers and on the stack. Closures are called via `objc_msgSend` which dynamically pushes the arguments on the stack at runtime. If you don't know any better, be quiet. – Brandon Jul 09 '16 at 22:42
  • You can quote whatever you want, from wherever you want. Until you look into the details, don't bother trying to tell me otherwise. – Brandon Jul 09 '16 at 22:43
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/116894/discussion-between-kametrixom-and-brandon). – Kametrixom Jul 09 '16 at 22:43