Both this declaration
protocol SomeProtocol : AnyObject { } and this declaration
protocol SomeProtocol : class { } seem to make it so that only classes can conform to this protocol (i.e. that the instances of the protocol are references to objects), and have no other effects.
Is there any difference between them? Should one be preferred over the other? If not, why is there two ways to do the same thing?
I am using the latest released Xcode 6.3.1.
You can create objects from classes, whereas protocols are just type definitions. Try to think of protocols as being abstract definitions, whereas classes and structs are real things you can create.
AnyObject is a protocol to which all classes implicitly conform. In fact, the standard library contains a type alias AnyClass representing AnyObject. Type . You can use AnyObject if you need the flexibility of an untyped object.
AnyObject is only for reference types (classes), Any is for both value and reference types. So you should go for [String: Any] . Swift provides two special types for working with nonspecific types: Any can represent an instance of any type at all, including function types.
Protocols let you describe what methods something should have, but don't provide the code inside. Extensions let you provide the code inside your methods, but only affect one data type – you can't add the method to lots of types at the same time.
This was answered by an official Swift developer (Slava_Pestov) on the Swift forums. Here is the summary:
You should use AnyObject (protocol SomeProtocol: AnyObject).
AnyObject and class are equivalent. There is no difference.
class will eventually be deprecated.
Regarding the answer https://forums.swift.org/t/class-only-protocols-class-vs-anyobject/11507/4, this answer is deprecated. These words are the same now.
DEPRECATED
Update: After consulting with the powers that be, the two definitions are supposed to be equivalent, with AnyObject being used as a stand-in while class was being finished. In the future the latter will obviate the former but, for now, they do present a few minor differences.
The difference lies in the semantics of @objc declarations. With AnyObject, the expectation is that conforming classes may or may not be proper Objective-C objects, but the language treats them as such anyway (in that you lose static dispatch sometimes). The takeaway from this is that you can treat an AnyObject et al. protocol constraint as a way to ask for @objc member functions as shown in the example in documentation for AnyObject in the STL:
import Foundation class C { @objc func getCValue() -> Int { return 42 } } // If x has a method @objc getValue()->Int, call it and // return the result. Otherwise, return nil. func getCValue1(x: AnyObject) -> Int? { if let f: ()->Int = x.getCValue { // <=== return f() } return nil } // A more idiomatic implementation using "optional chaining" func getCValue2(x: AnyObject) -> Int? { return x.getCValue?() // <=== } // An implementation that assumes the required method is present func getCValue3(x: AnyObject) -> Int { // <=== return x.getCValue() // x.getCValue is implicitly unwrapped. // <=== } The same example falls over immediately if you change that to a class-deriving protocol:
import Foundation protocol SomeClass : class {} class C : SomeClass { @objc func getCValue() -> Int { return 42 } } // If x has a method @objc getValue()->Int, call it and // return the result. Otherwise, return nil. func getCValue1(x: SomeClass) -> Int? { if let f: ()->Int = x.getCValue { // <=== SomeClass has no member 'getCValue' return f() } return nil } // A more idiomatic implementation using "optional chaining" func getCValue2(x: SomeClass) -> Int? { return x.getCValue?() // <=== SomeClass has no member 'getCValue' } // An implementation that assumes the required method is present func getCValue3(x: SomeClass) -> Int { // <=== return x.getCValue() // <=== SomeClass has no member 'getCValue' } So it seems class is a more conservative version of AnyObject that should be used when you only care about reference semantics and not about dynamic member lookups or Objective-C bridging.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With