Skip to content

NSArray: Add missing init(array: NSArray) initializer. #2076

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 33 additions & 29 deletions Foundation/NSArray.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import CoreFoundation
open class NSArray : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSCoding {
private let _cfinfo = _CFInfo(typeID: CFArrayGetTypeID())
internal var _storage = [AnyObject]()

open var count: Int {
guard type(of: self) === NSArray.self || type(of: self) === NSMutableArray.self else {
NSRequiresConcreteImplementation()
Expand Down Expand Up @@ -74,7 +74,38 @@ open class NSArray : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSCo
self.init(array: objects)
}
}


public convenience init(object anObject: Any) {
self.init(array: [anObject])
}

public convenience init(array: [Any]) {
self.init(array: array, copyItems: false)
}

public convenience init(array: NSArray) {
self.init(array: array as [AnyObject], copyItems: true)
}

public convenience init(array: [Any], copyItems: Bool) {

let optionalArray : [AnyObject] =
copyItems ?
array.map { return __SwiftValue.store($0).copy() as! NSObject } :
array.map { return __SwiftValue.store($0) }

// This would have been nice, but "initializer delegation cannot be nested in another expression"
// optionalArray.withUnsafeBufferPointer { ptr in
// self.init(objects: ptr.baseAddress, count: array.count)
// }
let cnt = array.count
let buffer = UnsafeMutablePointer<AnyObject>.allocate(capacity: cnt)
buffer.initialize(from: optionalArray, count: cnt)
self.init(objects: buffer, count: cnt)
buffer.deinitialize(count: cnt)
buffer.deallocate()
}

open func encode(with aCoder: NSCoder) {
guard aCoder.allowsKeyedCoding else {
preconditionFailure("Unkeyed coding is unsupported.")
Expand Down Expand Up @@ -124,33 +155,6 @@ open class NSArray : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSCo
return NSMutableArray(array: self.allObjects)
}

public convenience init(object anObject: Any) {
self.init(array: [anObject])
}

public convenience init(array: [Any]) {
self.init(array: array, copyItems: false)
}

public convenience init(array: [Any], copyItems: Bool) {

let optionalArray : [AnyObject] =
copyItems ?
array.map { return __SwiftValue.store($0).copy() as! NSObject } :
array.map { return __SwiftValue.store($0) }

// This would have been nice, but "initializer delegation cannot be nested in another expression"
// optionalArray.withUnsafeBufferPointer { ptr in
// self.init(objects: ptr.baseAddress, count: array.count)
// }
let cnt = array.count
let buffer = UnsafeMutablePointer<AnyObject>.allocate(capacity: cnt)
buffer.initialize(from: optionalArray, count: cnt)
self.init(objects: buffer, count: cnt)
buffer.deinitialize(count: cnt)
buffer.deallocate()
}

open override func isEqual(_ value: Any?) -> Bool {
switch value {
case let other as [Any]:
Expand Down
10 changes: 10 additions & 0 deletions TestFoundation/TestNSArray.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ class TestNSArray : XCTestCase {
XCTAssertEqual(array3, array5)
XCTAssertEqual(array4, array5)

let mutArray = NSMutableArray(array: [1, 2, 3, 4])
let array6 = NSArray(array: mutArray)
XCTAssertEqual(array6, mutArray)
mutArray[0] = 0
XCTAssertNotEqual(array6, mutArray)

let array7 = NSMutableArray(array: mutArray)
XCTAssertEqual(array7, mutArray)
array7.removeObject(at: 3)
XCTAssertNotEqual(array7.count, mutArray.count)
}

func test_constructorWithCopyItems() {
Expand Down