Difference between Generics and AnyObject in Swift Difference between Generics and AnyObject in Swift ios ios

Difference between Generics and AnyObject in Swift


Generics are type safe, meaning if you pass a string as a generic and try to use as a integer the compiler will complain and you will not be able to compile your (which is good). (This happens because Swift is using Static typing, and is able to give you a compiler error)

If you use AnyObject the compiler has no idea if the object can be treated as a String or as an Integer. It will allow you to do whatever you want with it (which is bad).

e.g. if you try to pass a String when it the your previously used Integer the application will crash. (This happens because Swift is using Dynamic typing and will only give you a runtime crash)

Generics basically tells the compiler:

"I am going to give you a type later and I want you to enforce that type everywhere I specify."

AnyObject basically tells the compiler:

"Don't worry about this variable no need to enforce any type here let me do whatever I want to."


Note: Icaro's answer would still be the accepted answer, I am just extending his explanation.

TL;DR : Check Icaro's answer.

About the usage of AnyObject Icaro rightly puts:

Don't worry about this variable no need to enforce any type here let me do whatever I want to.

What does this mean? Let's take the code example in the question (I've gone a step up and changed AnyObject to Any without changing the meaning of the question):

func myFilter(source: [Any], predicate:(Any) -> Bool) -> [Any] {  var result = [Any]()  for i in source {    if predicate(i) {      result.append(i)    }  }  return result}

This means, the myFilter function takes in two arguments one source and a closure predicate. If you look closely, the contents of the source array can be ANYTHING. And the argument of the closure predicate can be ANYTHING as well. If we were to name these "ANYTHING"s -- say ANYTHING1 and ANYTHING2 -- this approach doesn't require ANYTHING1 to be equal to ANYTHING2.

Let's sit back and ponder over the implications of this...

Say, we want to filter out evens from an array of integers and let's use our Any filter for this

var ints = [1,2,3,4,5] as [Any]var predicate = { (a : Any) -> Bool in    return (a as! Int) % 2 == 0}let evens = myFilter(source: ints, predicate:predicate)

Wow, that worked, didn't it? All smiles? No.

Notice how in the line :

return (a as! Int) % 2 == 0

I'm forcefully down-casting a. This line would crash if a was anything other than an Int. But its usage is justified; after all, we want to just filter out the Ints and I am smart enough to use just an array of Ints.

But, because say, I am a naive programmer, I do this :

var ints = [1,2,3,4,5,"6"] as [Any]var predicate = { (a : Any) -> Bool in    return (a as! Int) % 2 == 0}let evens = myFilter(source: ints, predicate:predicate)

This happily compiles, but crashes in the runtime. If only there was a way, where the compiler would tell me that this line...

var ints = [1,2,3,4,5,"6"]

... was faulty, we would not have had a crash. I would have fixed it right away!

Turns out, there is. Generics. To quote Icaro again,

I am going to give you a type later and I want you to enforce that type everywhere I specify.

func myFilter<T>(source: [T], predicate:(T) -> Bool) -> [T] {    var result = [T]()    for i in source {        if predicate(i) {            result.append(i)        }    }    return result}var ints = [1,2,3,4,5,6]var predicate = { (a : Int) -> Bool in    return a % 2 == 0}let evens = myFilter(source: ints, predicate:predicate)

This new filter is awesome. It won't let me do :

let evens = myFilter(source: ints, predicate:predicate) because, the types of the predicate and source don't match. Compile time error.

Generics is generic in this way : in this specific example -- while at the point of writing the myFilter function, you do not need to give a type of the source or the argument that predicate takes, it's T, it's ANYTHING. But once I say that source is an array of ANYTHING, you HAVE to make sure the argument that the predicate accepts is the same ANYTHING. With the background of our previous ANYTHING1, ANYTHING2 nomenclature, we can say that generics forces ANYTHING1 to be equal to ANYTHING2


Consider that in the first function T is not a type, like is AnyObject, but a type variable; this means that in the first function you can pass an array of values of any type as first parameter, but a predicate which operates only on values of that specific type as second parameter. That is you can pass an array of strings and a predicate on strings, or an array of integers and a predicate on integers, while you cannot pass an array of integers and a predicate on strings. So, the body of the function is guaranteed to be correct for what concern the types.

Instead in the second example you can pass a value of any type and a predicate which operates on any (possibly different!) type, so that, if the predicate would be called in the body of the function with the value of the first parameter, then a dynamic type error could occur. Fortunately, the Swith typechecker marks the call of the predicate as type error, in order to prevent this possibility.