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