Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AnyObject not working in Xcode8 beta6?

Tags:

In Xcode8 beta6, the following code will cause a warning: 'is' test is always true. But it won't print pass.

    struct TestStruct {     }      //warning: 'is' test is always true     if TestStruct() is AnyObject {         print("pass")     } 

And the following code will cause a warning: Conditional cast from 'T' to 'AnyObject' always succeeds

public static func register<T>(_ protocolType: T.Type, observer: T) {      //Warning: Conditional cast from 'T' to 'AnyObject' always succeeds     guard let object = observer as? AnyObject else {         fatalError("expecting reference type but found value type: \(observer)")     }     //... } 
like image 492
Learing Avatar asked Aug 19 '16 07:08

Learing


People also ask

What can AnyObject represent?

AnyObject is a protocol that can represent an instance of any class type. It also has a more general counterpart, Any , which can represent any type at all (including structs and enums).

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 AnyObject?

You use AnyObject when you need the flexibility of an untyped object or when you use bridged Objective-C methods and properties that return an untyped result. AnyObject can be used as the concrete type for an instance of any class, class type, or class-only protocol.


2 Answers

The warning works as intended: the false return of TestStruct() is AnyObject, however, does not

The prior version of this answer perceived the warning,

'is' test is always true

as the bug, and contained some discussion as to why this perceived buggy warning would manifest itself. That TestStruct() is AnyObject evaluated to false at runtime, however, was perceived as expected behaviour.

Given the comments to the bug report filed by the OP (SR-2420), it seems the situation is the reverse: since Xcode 8/beta 6, the is test should always evaluate to true, and the bug the OP:s post is the fact that TestStruct() is AnyObject evaluates to false during runtime.

Joe Groff writes:

This is correct, because everything bridges to AnyObject now.

...

is/as AnyObject always succeed for all types now. It's behaving as intended.


The new SwiftValue box for conversion from Swift values to Obj-C objects

(for additional details, see discussion in the comments below, thanks @MartinR)

It seems as if Swift values that are not explicitly implemented to be bridgeable to Obj-C objects via e.g. conformance to _ObjectiveCBridgeable (see e.g. the following Q&A for details regarding _ObjectiveCBridgeable), will instead automatically make use of the new SwiftValue box to allow conversion to Obj-C objects.

The initial commit message for swift/stdlib/public/runtime/SwiftValue.mm reads:

Runtime: Implement an opaque 'SwiftValue' ObjC class to hold bridged values

If there's no better mapping for a Swift value into an Objective-C object for bridging purposes, we can fall back to boxing the value in a class. This class doesn't have any public interface beyond being NSObject-conforming in Objective-C, but is recognized by the Swift runtime so that it can be dynamically cast back to the boxed type.

like image 195
dfrib Avatar answered Oct 02 '22 00:10

dfrib


Long story short.

To check if value has a reference type:

if type(of: value) is AnyClass {     // ... } 

To check if type is a reference type:

if SomeType.self is AnyClass {    // ... } 

More helpful answers:

  • https://stackoverflow.com/a/39185374/746347
  • https://stackoverflow.com/a/39546887/746347
like image 29
mixel Avatar answered Oct 02 '22 00:10

mixel