Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between a protocol extended from AnyObject and a class-only protocol?

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.

like image 872
user102008 Avatar asked May 11 '15 20:05

user102008


People also ask

What is the difference between protocol and class?

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.

Is AnyObject a protocol?

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.

What is the difference between any and AnyObject in Swift?

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.

What is protocol extension?

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.


2 Answers

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.

like image 178
kgaidis Avatar answered Oct 12 '22 11:10

kgaidis


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.

like image 20
CodaFi Avatar answered Oct 12 '22 11:10

CodaFi