@RobNapier's answer is correct from a good programming point of view - I see no reason whatever to be doing what you are attempting, but it shows up something interesting.
Firstly, you cannot call your function with an array of anything - arrays, as structs, do not conform to AnyObject (classes do). However, you call the function by a forced cast - as anything can be cast to AnyObject (presumably by wrapping the struct in a degenerate class), the call compiles.
Secondly, your question has the inference the wrong way round - you say "Which suggest that for an empty array the cast fails." - not so, the cast succeeds in both cases...
Let's see what actually gets passed in:
class Pet { var name: String { return "" } }
class Dog: Pet { override var name: String { return "Fido" } }
class Cat: Pet { override var name: String { return "Cfor" } }
func myFuction(receivedObject: AnyObject) {
print("myFuction called with \(receivedObject)") // ***
if let validDogs = receivedObject as? [Dog] {
print("Received object is an array of dogs")
// Do something with valid dogs
}
if let validCats = receivedObject as? [Cat] {
print("Received object is an array of cats")
// Do something with valid cats
}
}
var a: [Cat] = [Cat()]
//myFuction(receivedObject: a) // Argument type '[Cat]' does not conform to expected type 'AnyObject'
myFuction(receivedObject: a as! AnyObject) // Forced cast from '[Cat]' to 'AnyObject' always succeeds; did you mean to use 'as'?
a = []
myFuction(receivedObject: a as! AnyObject) // Forced cast from '[Cat]' to 'AnyObject' always succeeds; did you mean to use 'as'?
Output:
myFuction called with (
"__lldb_expr_97.Cat"
)
Received object is an array of cats
myFuction called with (
)
Received object is an array of dogs
Received object is an array of cats
So, when it's called with a non-empty array, the type is inferred from the members and the cast only succeeds if the members are of the right type. An empty array has no members, and thus could equally well be [Cat] or [Dog] or indeed [String].
Try
let b = [Cat(), Dog()]
myFuction(receivedObject: b as! AnyObject)
This prints
myFuction called with (
"__lldb_expr_107.Cat",
"__lldb_expr_107.Dog"
)
(and does not print a cast "success")
The long and the short of it is
A) the force as! AnyObject effectively throws away the array type and passes something resembling a tuple of elements which your let _ = as? is able to reassemble into an array from the types of the elements.
B) re-read @RobNapier's answer - that's the way to go!
AnyObject, since an array is a struct, not a class. Unless it's anNSArray, of course. Show us how you call it.self.myFucntion(receivedObject: object as! AnyObject)[Cat()]- it doesn't compile.myFuction(receivedObject: [Cat()])- at least not in Xcode 9.1... You can callmyFuction(receivedObject: [Cat()] as! AnyObject)