forked from swiftlang/swift-corelibs-foundation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNSObject.swift
347 lines (300 loc) · 15 KB
/
NSObject.swift
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
// 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 {
}