1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413
|
// 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 compatibility.
#if !os(WASI)
@_exported import Dispatch
#endif
@_implementationOnly 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: AnyObject {
/// 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
}
}
@available(*, unavailable)
extension NSZone : @unchecked Sendable { }
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.
//@_nonSendable - TODO: Mark with attribute to indicate this pure abstract class defers Sendable annotation to its subclasses.
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
}
internal 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
}
/// The hash value.
///
/// `NSObject` implements this by returning `self.hash`.
///
/// `NSObject.hashValue` is not overridable; subclasses can customize hashing
/// by overriding the `hash` property.
///
/// **Axiom:** `x == y` implies `x.hashValue == y.hashValue`
///
/// - Note: the hash value is not guaranteed to be stable across
/// different invocations of the same program. Do not persist the
/// hash value across program runs.
public final var hashValue: Int {
return hash
}
/// Hashes the essential components of this value by feeding them into the
/// given hasher.
///
/// NSObject implements this by feeding `self.hash` to the hasher.
///
/// `NSObject.hash(into:)` is not overridable; subclasses can customize
/// hashing by overriding the `hash` property.
public final func hash(into hasher: inout Hasher) {
hasher.combine(self.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)
}
// Please note:
// the following methods are not overridable in swift-corelibs-foundation.
private class var nsObjectSuperclass: NSObject.Type? {
// Pretend that {Swift,}Foundation.NSObject is the top of the class hierarchy.
// On Darwin, avoids dipping into the class hierarchy that exists above this class,
// which is ultimately rooted in the ObjC NSObject class.
guard !(self == NSObject.self) else { return nil }
return _getSuperclass(self) as? NSObject.Type
}
public class var superclass: AnyClass? {
return nsObjectSuperclass
}
/// Returns a Boolean value that indicates whether the receiving
/// class is a subclass of, or identical to, a given class.
public class func isSubclass(of aClass: AnyClass) -> Bool {
var checkedClass: NSObject.Type? = self
while let thisClass = checkedClass {
if thisClass === aClass {
return true
}
checkedClass = thisClass.nsObjectSuperclass
}
return false
}
public func isMember(of aClass: AnyClass) -> Bool {
return type(of: self) === aClass
}
public func isKind(of aClass: AnyClass) -> Bool {
return type(of: self).isSubclass(of: aClass)
}
}
extension NSObject : CustomDebugStringConvertible {
}
extension NSObject : CustomStringConvertible {
}
|