Skip to content

Instantly share code, notes, and snippets.

@aleclarson
Last active August 29, 2015 14:14
Show Gist options
  • Save aleclarson/e076f1fa0fc4ebedc9a1 to your computer and use it in GitHub Desktop.
Save aleclarson/e076f1fa0fc4ebedc9a1 to your computer and use it in GitHub Desktop.
Casting to and from Any, AnyObject, and NSObject
// https://gist.github.com/aleclarson/e076f1fa0fc4ebedc9a1
//
// Check out this link for more information.
// https://gist.github.com/aleclarson/e076f1fa0fc4ebedc9a1#comment-1379921
import Foundation
// MARK: Type checking
/// Returns true if a value is an object.
func isObject <T> (value: T) -> Bool {
return reflect(value).objectIdentifier != nil
}
// MARK: Type casting
/// Ensures the given value is an AnyObject.
func toObject <T> (value: T!) -> _Object<T>! {
return value == nil ? nil : _Object<T>(value)
}
/// Ensures the given object is a specific value type.
///
/// Casts to the expected value type.
///
/// Typically, use this with an AnyObject returned from `toObject(_:)`.
///
func fromObject <T> (object: AnyObject!) -> T! {
return object == nil ? nil : (object as? _Object<T>)?.value
}
///// Ensures the given value is an NSObject.
func toNSObject <T> (value: T!) -> NSObject! {
return value == nil ? nil : _NSObject(_Object<T>(value))
}
//
///// Ensures the given NSObject is a specific value type.
/////
///// Casts to the expected value type.
/////
///// Typically, use this with an AnyObject returned from `toNSObject(_:)`.
/////
func fromNSObject <T> (object: AnyObject!) -> T! {
return object == nil ? nil : fromObject((object as? _NSObject)?.object) ?? _cast(object)
}
/// Casts a value to an inferred type, safely or unsafely.
///
/// Passing `nil` always returns `nil`.
///
/// Pass `true` for "unsafe" when you want to use `unsafeBitCast`.
///
func cast <T,U> (value: T!, _ unsafe: Bool = false) -> U! {
return value == nil ? nil : _cast(value, unsafe)
}
// MARK: Stand-in classes
/// An AnyObject disguised as an NSObject
class _NSObject : NSObject {
var object: AnyObject
init (_ object: AnyObject) { self.object = object }
}
/// An Any disguised as an AnyObject
class _Object <T> {
var value: T
init (_ value: T) { self.value = value }
}
// MARK: Private
private func _cast <T,U> (value: T, _ unsafe: Bool = false) -> U! {
return unsafe ? unsafeBitCast(value, U.self) : value as? U
}
private func _fromObject <T> (object: AnyObject) -> T! {
return (object as? _Object<T>)?.value ?? _cast(object)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment