blob: bd4fe3817760e6892661f57e0654fb85062b7f2d [file] [log] [blame]
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
// @_exported import of Dispatch here makes it available to all
// classes in Foundation and all sources that import Foundation.
// This brings it into line with Darwin usage for compatbility.
@_exported import Dispatch
import CoreFoundation
/// The `NSObjectProtocol` groups methods that are fundamental to all Foundation objects.
///
/// If an object conforms to this protocol, it can be considered a first-class object.
///
/// The Cocoa root class, NSObject, adopts this protocol, so all objects inheriting
/// from NSObject have the features described by this protocol.
public protocol NSObjectProtocol : class {
/// Returns a Boolean value that indicates whether the instance
/// and a given `object` are equal.
///
/// This method defines what it means for instances to be equal. For example, a container
/// object might define two containers as equal if their corresponding objects all respond
/// true to an `isEqual(_:)` request. See the `NSData`, `NSDictionary`, `NSArray`,
/// and `NSString` class specifications for examples of the use of this method.
///
/// If two objects are equal, they must have the same hash value.
/// This last point is particularly important if you define `isEqual(_:)` in a subclass
/// and intend to put instances of that subclass into a collection.
/// Make sure you also define hash in your subclass.
///
/// - Parameter object: The object to be compared to the instance.
/// May be `nil`, in which case this method returns `false`.
/// - Returns: `true` if the instance and `object` are equal, otherwise `false`.
func isEqual(_ object: Any?) -> Bool
/// Returns an integer that can be used as a table address in a hash table structure.
///
/// If two objects are equal (as determined by the `isEqual(_:)` method),
/// they must have the same hash value. This last point is particularly important
/// if you define `hash` in a subclass and intend to put instances of that subclass
/// into a collection.
///
/// If a mutable object is added to a collection that uses hash values to determine
/// the object’s position in the collection, the value returned by the `hash` property
/// of the object must not change while the object is in the collection. Therefore, either
/// the `hash` property must not rely on any of the object’s internal state information
/// or you must make sure the object’s internal state information does not change while
/// the object is in the collection. Thus, for example, a mutable dictionary can be put
/// in a hash table but you must not change it while it is in there.
/// (Note that it can be difficult to know whether or not a given object is in a collection.)
var hash: Int { get }
/// Returns the instance itself.
///
/// - Returns: The instance itself.
func `self`() -> Self
/// Returns a Boolean value that indicates whether the instance does not descend from NSObject.
///
/// - Returns: `false` if the instance really descends from `NSObject`, otherwise `true`.
func isProxy() -> Bool
/// Returns a string that describes the contents of the instance.
var description: String { get }
/// Returns a string that describes the contents of the instance for presentation
/// in the debugger.
var debugDescription: String { get }
}
extension NSObjectProtocol {
public var debugDescription: String {
return description
}
}
public struct NSZone : ExpressibleByNilLiteral {
public init() {
}
public init(nilLiteral: ()) {
}
}
/// The `NSCopying` protocol declares a method for providing functional copies of an object.
/// The exact meaning of “copy” can vary from class to class, but a copy must be a functionally
/// independent object with values identical to the original at the time the copy was made.
///
/// NSCopying declares one method, `copy(with:)`, but copying is commonly invoked with the
/// convenience method `copy`. The copy method is defined for all objects inheriting from NSObject
/// and simply invokes `copy(with:)` with the `nil` zone.
///
/// If a subclass inherits `NSCopying` from its superclass and declares additional instance variables,
/// the subclass has to override `copy(with:)` to properly handle its own instance variables,
/// invoking the superclass’s implementation first.
public protocol NSCopying {
/// Returns a new instance that’s a copy of the current one.
///
/// - Parameter zone: This parameter is ignored. Memory zones are no longer used.
/// - Returns: A new instance that’s a copy of the current one.
func copy(with zone: NSZone?) -> Any
}
extension NSCopying {
/// Returns a new instance that’s a copy of the current one.
///
/// - Returns: A new instance that’s a copy of the current one.
public func copy() -> Any {
return copy(with: nil)
}
}
/// The `NSMutableCopying` protocol declares a method for providing mutable
/// copies of an object. Only classes that define an “immutable vs. mutable” distinction
/// should adopt this protocol. Classes that don’t define such a distinction should
/// adopt `NSCopying` instead.
public protocol NSMutableCopying {
/// Returns a new instance that’s a mutable copy of the current one.
///
/// - Parameter zone: This parameter is ignored. Memory zones are no longer used.
/// - Returns: A new instance that’s a mutable copy of the current one.
func mutableCopy(with zone: NSZone?) -> Any
}
extension NSMutableCopying {
/// Returns a new instance that’s a mutable copy of the current one.
///
/// - Returns: A new instance that’s a mutable copy of the current one.
public func mutableCopy() -> Any {
return mutableCopy(with: nil)
}
}
/// The root class of most Foundation class hierarchies.
open class NSObject : NSObjectProtocol, Equatable, Hashable {
// Important: add no ivars here. It will subvert the careful layout of subclasses that bridge into CF.
/// Implemented by subclasses to initialize a new object immediately after memory
/// for it has been allocated.
public init() {}
/// Returns the object returned by `copy(with:)`.
///
/// This is a convenience method for classes that adopt the `NSCopying` protocol.
/// `NSObject` does not itself support the `NSCopying` protocol.
/// Subclasses must support the protocol and implement the `copy(with:)` method.
/// A subclass version of the `copy(with:)` method should invoke `super`'s method first,
/// to incorporate its implementation, unless the subclass descends directly from `NSObject`.
///
/// - Returns: The object returned by the `NSCopying` protocol method `copy(with:)`.
open func copy() -> Any {
if let copyable = self as? NSCopying {
return copyable.copy(with: nil)
}
return self
}
/// Returns the object returned by `mutableCopy(with:)` where the zone is `nil.`
///
/// This is a convenience method for classes that adopt the `NSMutableCopying` protocol.
///
/// - Returns: The object returned by the `NSMutableCopying` protocol method
/// `mutableCopy(with:)`, where the zone is `nil`.
open func mutableCopy() -> Any {
if let copyable = self as? NSMutableCopying {
return copyable.mutableCopy(with: nil)
}
return self
}
/// Returns a Boolean value that indicates whether the instance is equal to another given object.
///
/// The default implementation for this method provided by `NSObject` returns `true` if
/// the objects being compared refer to the same instance.
///
/// - Parameter object: The object with which to compare the instance.
/// - Returns: `true` if the instance is equal to `object`, otherwise `false`.
open func isEqual(_ object: Any?) -> Bool {
guard let obj = object as? NSObject else { return false }
return obj === self
}
/// Returns an integer that can be used as a table address in a hash table structure.
///
/// If two objects are equal (as determined by the `isEqual(_:)` method),
/// they must have the same hash value. This last point is particularly important
/// if you define `hash` in a subclass and intend to put instances of that subclass
/// into a collection.
///
/// If a mutable object is added to a collection that uses hash values to determine
/// the object’s position in the collection, the value returned by the `hash` property
/// of the object must not change while the object is in the collection. Therefore, either
/// the `hash` property must not rely on any of the object’s internal state information
/// or you must make sure the object’s internal state information does not change while
/// the object is in the collection. Thus, for example, a mutable dictionary can be put
/// in a hash table but you must not change it while it is in there.
/// (Note that it can be difficult to know whether or not a given object is in a collection.)
open var hash: Int {
return ObjectIdentifier(self).hashValue
}
/// Returns the instance itself.
///
/// - Returns: The instance itself.
open func `self`() -> Self {
return self
}
/// Returns a Boolean value that indicates whether the instance does not descend from NSObject.
///
/// - Returns: `false` if the instance really descends from `NSObject`, otherwise `true`.
open func isProxy() -> Bool {
return false
}
/// Returns a string that describes the contents of the instance.
open var description: String {
return "<\(type(of: self)): \(Unmanaged.passUnretained(self).toOpaque())>"
}
/// Returns a string that describes the contents of the instance for presentation
/// in the debugger.
open var debugDescription: String {
return description
}
open var _cfTypeID: CFTypeID {
return 0
}
// TODO: move these back into extensions once extension methods can be overriden
/// Overridden by subclasses to substitute a class other than its own during coding.
///
/// This property is needed for `NSCoder`.
/// `NSObject`’s implementation returns the instance's class.
/// The private subclasses of a class cluster substitute the name of their public
/// superclass when being archived.
open var classForCoder: AnyClass {
return type(of: self)
}
/// Overridden by subclasses to substitute another object for itself during encoding.
///
/// An object might encode itself into an archive, but encode a proxy for itself if
/// it’s being encoded for distribution. This method is invoked by `NSCoder`.
/// `NSObject`’s implementation returns `self`.
///
/// - Parameter aCoder: The coder encoding the instance.
/// - Returns: The object encode instead of the instance (if different).
open func replacementObject(for aCoder: NSCoder) -> Any? {
return self
}
// TODO: Could perhaps be an extension of NSCoding instead.
// The reason it is an extension of NSObject is the lack of default
// implementations on protocols in Objective-C.
/// Subclasses to substitute a new class for instances during keyed archiving.
///
/// The object will be encoded as if it were a member of the class. This property is
/// overridden by the encoder class and instance name to class encoding tables.
/// If this property is `nil`, the result of this property is ignored.
open var classForKeyedArchiver: AnyClass? {
return self.classForCoder
}
/// Overridden by subclasses to substitute another object for itself during keyed archiving.
///
/// This method is called only if no replacement mapping for the object has been set up
/// in the encoder (for example, due to a previous call of `replacementObject(for:)` to that object).
///
/// - Parameter archiver: A keyed archiver creating an archive.
/// - Returns: The object encode instead of the instance (if different).
open func replacementObject(for archiver: NSKeyedArchiver) -> Any? {
return self.replacementObject(for: archiver as NSCoder)
}
/// Overridden to return the names of classes that can be used to decode
/// objects if their class is unavailable.
///
/// `NSKeyedArchiver` calls this method and stores the result inside the archive.
/// If the actual class of an object doesn’t exist at the time of unarchiving,
/// `NSKeyedUnarchiver` goes through the stored list of classes and uses the first one
/// that does exists as a substitute class for decoding the object.
/// The default implementation of this method returns empty array.
///
/// You can use this method if you introduce a new class into your application to provide
/// some backwards compatibility in case the archive will be read on a system that does not
/// have that class. Sometimes there may be another class which may work nearly as well as
/// a substitute for the new class, and the archive keys and archived state for the new class
/// can be carefully chosen (or compatibility written out) so that the object can be unarchived
/// as the substitute class if necessary.
///
/// - Returns: An array of strings that specify the names of classes in preferred order for unarchiving.
open class func classFallbacksForKeyedArchiver() -> [String] {
return []
}
/// Overridden by subclasses to substitute a new class during keyed unarchiving.
///
/// During keyed unarchiving, instances of the class will be decoded as members
/// of the returned class. This method overrides the results of the decoder’s class
/// and instance name to class encoding tables.
///
/// - Returns: The class to substitute for the current class during keyed unarchiving.
open class func classForKeyedUnarchiver() -> AnyClass {
return self
}
open var hashValue: Int {
return hash
}
/// Returns a Boolean value indicating whether two values are equal.
///
/// Equality is the inverse of inequality. For any values `a` and `b`,
/// `a == b` implies that `a != b` is `false`.
///
/// - Parameters:
/// - lhs: A value to compare.
/// - rhs: Another value to compare.
public static func ==(lhs: NSObject, rhs: NSObject) -> Bool {
return lhs.isEqual(rhs)
}
}
extension NSObject : CustomDebugStringConvertible {
}
extension NSObject : CustomStringConvertible {
}