EnumerateUsingObjects in Swift


(Doug Hill) #1

I'm trying to accomplish the equivalent functionality of -[NSArray enumerateUsingObjects:…] in Swift. Doing a Googles search, I see that one would need to call the equivalent method on the bridged NSArray version of your Swift array:

var myNSArray : NSArray = mySwiftArray as NSArray

Here's the problem I'm running into; I have the following class:

class Tester<typeA>
{
  var myArray : [typeA]

  init()
  {
    var temp = self. myArray as NSArray
  }
}

Which produces a compiler error:

'cannot convert value of type '[typeA]' to type 'NSArray' in coercion'

Ok, this makes some sense since I'm guessing NSArray requires each element to to be an NSObject but this array type Array<typeA> could be a non-NSObject.

However, this makes my code harder to write since I now have to make sure any array has element type NSObject to use enumerateUsingObjects. Not something I can either guarantee or even desire.

The reason I like enumerateUsingObjects is that it supports a functional style of programming and is better at creating work items for each object by dispatching each array item on multiple cores/processors/threads for me. Writing this method myself would require figuring out to pass an object to a dispatch invocation. But looking through the swift API's, I don't see any GCD method for passing an object to dispatch_sync/async. I see versions of these methods that takes a context parameter but then takes a C function instead of a block, so not very Swift-like and potentially unsafe.

Does this mean enumerateUsingObjects is generally not all that useful in Swift? Are there better alternatives? Any ideas on how best to handle this situation would be appreciated.

Doug Hill


(Jon Shier) #2

enumerateObjects(options:using:) exists on NSArray in Swift. And I was able to create your generic class just fine:

class Test<T> {
    var array: [T] = []
    
    init() {
        var temp = array as NSArray
    }
}

I’m not sure what the canonical parallel array enumeration would be, but you can do it using concurrentPerform:

let array = [“one”, “two”]
DispatchQueue.concurrentPerform(iterations: array.count) { index in
    print(array[index])
}

···

On Jan 23, 2017, at 8:20 PM, Doug Hill via swift-users <swift-users@swift.org> wrote:

I'm trying to accomplish the equivalent functionality of -[NSArray enumerateUsingObjects:…] in Swift. Doing a Googles search, I see that one would need to call the equivalent method on the bridged NSArray version of your Swift array:

var myNSArray : NSArray = mySwiftArray as NSArray

Here's the problem I'm running into; I have the following class:

class Tester<typeA>
{
  var myArray : [typeA]

  init()
  {
    var temp = self. myArray as NSArray
  }
}

Which produces a compiler error:

'cannot convert value of type '[typeA]' to type 'NSArray' in coercion'

Ok, this makes some sense since I'm guessing NSArray requires each element to to be an NSObject but this array type Array<typeA> could be a non-NSObject.

However, this makes my code harder to write since I now have to make sure any array has element type NSObject to use enumerateUsingObjects. Not something I can either guarantee or even desire.

The reason I like enumerateUsingObjects is that it supports a functional style of programming and is better at creating work items for each object by dispatching each array item on multiple cores/processors/threads for me. Writing this method myself would require figuring out to pass an object to a dispatch invocation. But looking through the swift API's, I don't see any GCD method for passing an object to dispatch_sync/async. I see versions of these methods that takes a context parameter but then takes a C function instead of a block, so not very Swift-like and potentially unsafe.

Does this mean enumerateUsingObjects is generally not all that useful in Swift? Are there better alternatives? Any ideas on how best to handle this situation would be appreciated.

Doug Hill
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Zhao Xin) #3

It seems to me that you didn't initialize your `myArray` before you casted
it. That caused the problem.

Zhaoxin

···

On Tue, Jan 24, 2017 at 9:34 AM, Jon Shier via swift-users < swift-users@swift.org> wrote:

enumerateObjects(options:using:) exists on NSArray in Swift. And I was
able to create your generic class just fine:

class Test<T> {
    var array: [T] = []

    init() {
        var temp = array as NSArray
    }
}

I’m not sure what the canonical parallel array enumeration would be, but
you can do it using concurrentPerform:

let array = [“one”, “two”]
DispatchQueue.concurrentPerform(iterations: array.count) { index in
    print(array[index])
}

On Jan 23, 2017, at 8:20 PM, Doug Hill via swift-users < > swift-users@swift.org> wrote:

I'm trying to accomplish the equivalent functionality of -[NSArray
enumerateUsingObjects:…] in Swift. Doing a Googles search, I see that one
would need to call the equivalent method on the bridged NSArray version of
your Swift array:

var myNSArray : NSArray = mySwiftArray as NSArray

Here's the problem I'm running into; I have the following class:

class Tester<typeA>
{
var myArray : [typeA]

init()
{
var temp = self. myArray as NSArray
}
}

Which produces a compiler error:

'cannot convert value of type '[typeA]' to type 'NSArray' in coercion'

Ok, this makes some sense since I'm guessing NSArray requires each element
to to be an NSObject but this array type Array<typeA> could be a
non-NSObject.

However, this makes my code harder to write since I now have to make sure
any array has element type NSObject to use enumerateUsingObjects. Not
something I can either guarantee or even desire.

The reason I like enumerateUsingObjects is that it supports a functional
style of programming and is better at creating work items for each object
by dispatching each array item on multiple cores/processors/threads for me.
Writing this method myself would require figuring out to pass an object to
a dispatch invocation. But looking through the swift API's, I don't see any
GCD method for passing an object to dispatch_sync/async. I see versions of
these methods that takes a context parameter but then takes a C function
instead of a block, so not very Swift-like and potentially unsafe.

Does this mean enumerateUsingObjects is generally not all that useful in
Swift? Are there better alternatives? Any ideas on how best to handle this
situation would be appreciated.

Doug Hill
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Doug Hill) #4

Thanks for the tip about 'concurrentPerform'!

···

On Jan 23, 2017, at 5:34 PM, Jon Shier <jon@jonshier.com> wrote:

enumerateObjects(options:using:) exists on NSArray in Swift. And I was able to create your generic class just fine:

class Test<T> {
    var array: [T] = []
    
    init() {
        var temp = array as NSArray
    }
}

I’m not sure what the canonical parallel array enumeration would be, but you can do it using concurrentPerform:

let array = [“one”, “two”]
DispatchQueue.concurrentPerform(iterations: array.count) { index in
    print(array[index])
}

On Jan 23, 2017, at 8:20 PM, Doug Hill via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

I'm trying to accomplish the equivalent functionality of -[NSArray enumerateUsingObjects:…] in Swift. Doing a Googles search, I see that one would need to call the equivalent method on the bridged NSArray version of your Swift array:

var myNSArray : NSArray = mySwiftArray as NSArray

Here's the problem I'm running into; I have the following class:

class Tester<typeA>
{
  var myArray : [typeA]

  init()
  {
    var temp = self. myArray as NSArray
  }
}

Which produces a compiler error:

'cannot convert value of type '[typeA]' to type 'NSArray' in coercion'

Ok, this makes some sense since I'm guessing NSArray requires each element to to be an NSObject but this array type Array<typeA> could be a non-NSObject.

However, this makes my code harder to write since I now have to make sure any array has element type NSObject to use enumerateUsingObjects. Not something I can either guarantee or even desire.

The reason I like enumerateUsingObjects is that it supports a functional style of programming and is better at creating work items for each object by dispatching each array item on multiple cores/processors/threads for me. Writing this method myself would require figuring out to pass an object to a dispatch invocation. But looking through the swift API's, I don't see any GCD method for passing an object to dispatch_sync/async. I see versions of these methods that takes a context parameter but then takes a C function instead of a block, so not very Swift-like and potentially unsafe.

Does this mean enumerateUsingObjects is generally not all that useful in Swift? Are there better alternatives? Any ideas on how best to handle this situation would be appreciated.

Doug Hill
_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Doug Hill) #5

Thanks for the help. I'm still trying to figure out how Swift works, particularly what the error messages mean. This has been driving me a little nuts trying to figure out what is wrong via sometimes cryptic errors. Also, it seems like getting generic programming working in Swift is more difficult than I'm used to (even than C++!) so this answer helps figure out how the compiler works.

Doug Hill

···

On Jan 23, 2017, at 7:04 PM, Zhao Xin <owenzx@gmail.com> wrote:

It seems to me that you didn't initialize your `myArray` before you casted it. That caused the problem.

Zhaoxin

On Tue, Jan 24, 2017 at 9:34 AM, Jon Shier via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
enumerateObjects(options:using:) exists on NSArray in Swift. And I was able to create your generic class just fine:

class Test<T> {
    var array: [T] = []
    
    init() {
        var temp = array as NSArray
    }
}

I’m not sure what the canonical parallel array enumeration would be, but you can do it using concurrentPerform:

let array = [“one”, “two”]
DispatchQueue.concurrentPerform(iterations: array.count) { index in
    print(array[index])
}

On Jan 23, 2017, at 8:20 PM, Doug Hill via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

I'm trying to accomplish the equivalent functionality of -[NSArray enumerateUsingObjects:…] in Swift. Doing a Googles search, I see that one would need to call the equivalent method on the bridged NSArray version of your Swift array:

var myNSArray : NSArray = mySwiftArray as NSArray

Here's the problem I'm running into; I have the following class:

class Tester<typeA>
{
  var myArray : [typeA]

  init()
  {
    var temp = self. myArray as NSArray
  }
}

Which produces a compiler error:

'cannot convert value of type '[typeA]' to type 'NSArray' in coercion'

Ok, this makes some sense since I'm guessing NSArray requires each element to to be an NSObject but this array type Array<typeA> could be a non-NSObject.

However, this makes my code harder to write since I now have to make sure any array has element type NSObject to use enumerateUsingObjects. Not something I can either guarantee or even desire.

The reason I like enumerateUsingObjects is that it supports a functional style of programming and is better at creating work items for each object by dispatching each array item on multiple cores/processors/threads for me. Writing this method myself would require figuring out to pass an object to a dispatch invocation. But looking through the swift API's, I don't see any GCD method for passing an object to dispatch_sync/async. I see versions of these methods that takes a context parameter but then takes a C function instead of a block, so not very Swift-like and potentially unsafe.

Does this mean enumerateUsingObjects is generally not all that useful in Swift? Are there better alternatives? Any ideas on how best to handle this situation would be appreciated.

Doug Hill


(Doug Hill) #6

OK, I just tried testing this code in my app and a Swift playground. I also tried a variation on the initializer just for the heck of it. I get the following error:

class Test<T>
{
    var array:[T] = []
    var array2 = [T]()

    init() {
        var temp = self.array as NSArray
        var temp2 = self.array2 as NSArray
    }
}

error: cannot convert value of type '[T]' to type 'NSArray' in coercion
                var temp = self.array as NSArray
                           ~~~~~^
error: cannot convert value of type '[T]' to type 'NSArray' in coercion
                var temp2 = self.array2 as NSArray
                            ~~~~~^

Are there restrictions on what can be converted to NSArray?

Doug Hill

···

On Jan 25, 2017, at 9:24 AM, Doug Hill via swift-users <swift-users@swift.org> wrote:

Thanks for the help. I'm still trying to figure out how Swift works, particularly what the error messages mean. This has been driving me a little nuts trying to figure out what is wrong via sometimes cryptic errors. Also, it seems like getting generic programming working in Swift is more difficult than I'm used to (even than C++!) so this answer helps figure out how the compiler works.

Doug Hill

On Jan 23, 2017, at 7:04 PM, Zhao Xin <owenzx@gmail.com <mailto:owenzx@gmail.com>> wrote:

It seems to me that you didn't initialize your `myArray` before you casted it. That caused the problem.

Zhaoxin

On Tue, Jan 24, 2017 at 9:34 AM, Jon Shier via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
enumerateObjects(options:using:) exists on NSArray in Swift. And I was able to create your generic class just fine:

class Test<T> {
    var array: [T] = []
    
    init() {
        var temp = array as NSArray
    }
}


(Doug Hill) #7

I'm guessing that conversion of a Swift array to an NSArray can only happen if the Swift array holds NSObjects. So, I tried changing the type parameter of my class to NSObject:

class Test<NSObject>
{
    let array = [NSObject]()

    init() {
        let temp = self.array as NSArray
    }
}

error: cannot convert value of type '[NSObject]' to type 'NSArray' in coercion
        var temp = self.array as NSArray
                    ~~~~~^~~~~

However, if I change the type parameter to something else it compiles with no problem.

class Test<T>
{
    let array = [NSObject]()

    init() {
        let temp = self.array as NSArray
    }
}

I guess this is interesting, but I still can't create an array with items whose type is the type parameter of the class and then convert to NSArray.

Doug Hill

···

On Jan 25, 2017, at 10:49 AM, Doug Hill <swiftusers@breaqz.com> wrote:

OK, I just tried testing this code in my app and a Swift playground. I also tried a variation on the initializer just for the heck of it. I get the following error:

class Test<T>
{
    var array:[T] = []
    var array2 = [T]()

    init() {
        var temp = self.array as NSArray
        var temp2 = self.array2 as NSArray
    }
}

error: cannot convert value of type '[T]' to type 'NSArray' in coercion
                var temp = self.array as NSArray
                           ~~~~~^
error: cannot convert value of type '[T]' to type 'NSArray' in coercion
                var temp2 = self.array2 as NSArray
                            ~~~~~^

Are there restrictions on what can be converted to NSArray?

Doug Hill

On Jan 25, 2017, at 9:24 AM, Doug Hill via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Thanks for the help. I'm still trying to figure out how Swift works, particularly what the error messages mean. This has been driving me a little nuts trying to figure out what is wrong via sometimes cryptic errors. Also, it seems like getting generic programming working in Swift is more difficult than I'm used to (even than C++!) so this answer helps figure out how the compiler works.

Doug Hill

On Jan 23, 2017, at 7:04 PM, Zhao Xin <owenzx@gmail.com <mailto:owenzx@gmail.com>> wrote:

It seems to me that you didn't initialize your `myArray` before you casted it. That caused the problem.

Zhaoxin

On Tue, Jan 24, 2017 at 9:34 AM, Jon Shier via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
enumerateObjects(options:using:) exists on NSArray in Swift. And I was able to create your generic class just fine:

class Test<T> {
    var array: [T] = []
    
    init() {
        var temp = array as NSArray
    }
}


(Zhao Xin) #8

Can you check the version of you Swift? Your code works in Xcode 8.2.1
(8C1002), Swift 3.0.2 (swiftlang-800.0.63 clang-800.0.42.1)

Zhaoxin

···

On Thu, Jan 26, 2017 at 2:49 AM, Doug Hill <swiftusers@breaqz.com> wrote:

OK, I just tried testing this code in my app and a Swift playground. I
also tried a variation on the initializer just for the heck of it. I get
the following error:

class Test<T>
{
    var array:[T] = []
    var array2 = [T]()

    init() {
        var temp = self.array as NSArray
        var temp2 = self.array2 as NSArray
    }
}

*error: cannot convert value of type '[T]' to type 'NSArray' in coercion*
* var temp = self.array as NSArray*
* ~~~~~^*
*error: cannot convert value of type '[T]' to type 'NSArray' in coercion*
* var temp2 = self.array2 as NSArray*
* ~~~~~^*

Are there restrictions on what can be converted to NSArray?

Doug Hill

On Jan 25, 2017, at 9:24 AM, Doug Hill via swift-users < > swift-users@swift.org> wrote:

Thanks for the help. I'm still trying to figure out how Swift works,
particularly what the error messages mean. This has been driving me a
little nuts trying to figure out what is wrong via sometimes cryptic
errors. Also, it seems like getting generic programming working in Swift is
more difficult than I'm used to (even than C++!) so this answer helps
figure out how the compiler works.

Doug Hill

On Jan 23, 2017, at 7:04 PM, Zhao Xin <owenzx@gmail.com> wrote:

It seems to me that you didn't initialize your `myArray` before you
casted it. That caused the problem.

Zhaoxin

On Tue, Jan 24, 2017 at 9:34 AM, Jon Shier via swift-users < > swift-users@swift.org> wrote:

enumerateObjects(options:using:) exists on NSArray in Swift. And I was
able to create your generic class just fine:

class Test<T> {
    var array: [T] = []

    init() {
        var temp = array as NSArray
    }
}


(Doug Hill) #9

For reasons, I'm still using Xcode 7 and Swift 2.2

Apple Swift version 2.2 (swiftlang-703.0.18.8 clang-703.0.31)

Doug Hill

···

On Jan 25, 2017, at 5:13 PM, Zhao Xin <owenzx@gmail.com> wrote:

Can you check the version of you Swift? Your code works in Xcode 8.2.1 (8C1002), Swift 3.0.2 (swiftlang-800.0.63 clang-800.0.42.1)

Zhaoxin

On Thu, Jan 26, 2017 at 2:49 AM, Doug Hill <swiftusers@breaqz.com <mailto:swiftusers@breaqz.com>> wrote:
OK, I just tried testing this code in my app and a Swift playground. I also tried a variation on the initializer just for the heck of it. I get the following error:

class Test<T>
{
    var array:[T] = []
    var array2 = [T]()

    init() {
        var temp = self.array as NSArray
        var temp2 = self.array2 as NSArray
    }
}

error: cannot convert value of type '[T]' to type 'NSArray' in coercion
                var temp = self.array as NSArray
                           ~~~~~^
error: cannot convert value of type '[T]' to type 'NSArray' in coercion
                var temp2 = self.array2 as NSArray
                            ~~~~~^

Are there restrictions on what can be converted to NSArray?

Doug Hill

On Jan 25, 2017, at 9:24 AM, Doug Hill via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Thanks for the help. I'm still trying to figure out how Swift works, particularly what the error messages mean. This has been driving me a little nuts trying to figure out what is wrong via sometimes cryptic errors. Also, it seems like getting generic programming working in Swift is more difficult than I'm used to (even than C++!) so this answer helps figure out how the compiler works.

Doug Hill

On Jan 23, 2017, at 7:04 PM, Zhao Xin <owenzx@gmail.com <mailto:owenzx@gmail.com>> wrote:

It seems to me that you didn't initialize your `myArray` before you casted it. That caused the problem.

Zhaoxin

On Tue, Jan 24, 2017 at 9:34 AM, Jon Shier via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
enumerateObjects(options:using:) exists on NSArray in Swift. And I was able to create your generic class just fine:

class Test<T> {
    var array: [T] = []
    
    init() {
        var temp = array as NSArray
    }
}


(Zhao Xin) #10

I think in swift 2.x, the `Array` is not mature enough to do a lot of
things. Besides, `NSArray` can also hold non-NSObjects like Int, for
example.

I suggest you to use the latest Swift to do your research. As in Swift,
everything moves fast and changes a lot. In the latest Xcode beta, all
swift 2.x are abandoned. The latest stable swift is 3.0.2 and 2.3. The next
release will be swift 3.1.

Zhaoxin

···

On Thu, Jan 26, 2017 at 9:17 AM, Doug Hill <swiftusers@breaqz.com> wrote:

I'm guessing that conversion of a Swift array to an NSArray can only
happen if the Swift array holds NSObjects. So, I tried changing the type
parameter of my class to NSObject:

class Test<NSObject>
{
    let array = [NSObject]()

    init() {
        let temp = self.array as NSArray
    }
}

error: cannot convert value of type '[NSObject]' to type 'NSArray' in
coercion
        var temp = self.array as NSArray
                    ~~~~~^~~~~

However, if I change the type parameter to something else it compiles with
no problem.

class Test<T>
{
    let array = [NSObject]()

    init() {
        let temp = self.array as NSArray
    }
}

I guess this is interesting, but I still can't create an array with items
whose type is the type parameter of the class and then convert to NSArray.

Doug Hill

On Jan 25, 2017, at 10:49 AM, Doug Hill <swiftusers@breaqz.com> wrote:

OK, I just tried testing this code in my app and a Swift playground. I
also tried a variation on the initializer just for the heck of it. I get
the following error:

class Test<T>
{
    var array:[T] = []
    var array2 = [T]()

    init() {
        var temp = self.array as NSArray
        var temp2 = self.array2 as NSArray
    }
}

*error: cannot convert value of type '[T]' to type 'NSArray' in coercion*
* var temp = self.array as NSArray*
* ~~~~~^*
*error: cannot convert value of type '[T]' to type 'NSArray' in coercion*
* var temp2 = self.array2 as NSArray*
* ~~~~~^*

Are there restrictions on what can be converted to NSArray?

Doug Hill

On Jan 25, 2017, at 9:24 AM, Doug Hill via swift-users < > swift-users@swift.org> wrote:

Thanks for the help. I'm still trying to figure out how Swift works,
particularly what the error messages mean. This has been driving me a
little nuts trying to figure out what is wrong via sometimes cryptic
errors. Also, it seems like getting generic programming working in Swift is
more difficult than I'm used to (even than C++!) so this answer helps
figure out how the compiler works.

Doug Hill

On Jan 23, 2017, at 7:04 PM, Zhao Xin <owenzx@gmail.com> wrote:

It seems to me that you didn't initialize your `myArray` before you
casted it. That caused the problem.

Zhaoxin

On Tue, Jan 24, 2017 at 9:34 AM, Jon Shier via swift-users < > swift-users@swift.org> wrote:

enumerateObjects(options:using:) exists on NSArray in Swift. And I was
able to create your generic class just fine:

class Test<T> {
    var array: [T] = []

    init() {
        var temp = array as NSArray
    }
}


(Doug Hill) #11

Unfortunately, this is for a work-related project, not just research, so I'm looking for solutions to specific problems that I'll need for my work.

I guess I'll have to file this one away as broken in Swift 2.x

Doug

···

On Jan 25, 2017, at 5:28 PM, Zhao Xin <owenzx@gmail.com> wrote:

I think in swift 2.x, the `Array` is not mature enough to do a lot of things. Besides, `NSArray` can also hold non-NSObjects like Int, for example.

I suggest you to use the latest Swift to do your research. As in Swift, everything moves fast and changes a lot. In the latest Xcode beta, all swift 2.x are abandoned. The latest stable swift is 3.0.2 and 2.3. The next release will be swift 3.1.

Zhaoxin

On Thu, Jan 26, 2017 at 9:17 AM, Doug Hill <swiftusers@breaqz.com <mailto:swiftusers@breaqz.com>> wrote:
I'm guessing that conversion of a Swift array to an NSArray can only happen if the Swift array holds NSObjects. So, I tried changing the type parameter of my class to NSObject:

class Test<NSObject>
{
    let array = [NSObject]()

    init() {
        let temp = self.array as NSArray
    }
}

error: cannot convert value of type '[NSObject]' to type 'NSArray' in coercion
        var temp = self.array as NSArray
                    ~~~~~^~~~~

However, if I change the type parameter to something else it compiles with no problem.

class Test<T>
{
    let array = [NSObject]()

    init() {
        let temp = self.array as NSArray
    }
}

I guess this is interesting, but I still can't create an array with items whose type is the type parameter of the class and then convert to NSArray.

Doug Hill

On Jan 25, 2017, at 10:49 AM, Doug Hill <swiftusers@breaqz.com <mailto:swiftusers@breaqz.com>> wrote:

OK, I just tried testing this code in my app and a Swift playground. I also tried a variation on the initializer just for the heck of it. I get the following error:

class Test<T>
{
    var array:[T] = []
    var array2 = [T]()

    init() {
        var temp = self.array as NSArray
        var temp2 = self.array2 as NSArray
    }
}

error: cannot convert value of type '[T]' to type 'NSArray' in coercion
                var temp = self.array as NSArray
                           ~~~~~^
error: cannot convert value of type '[T]' to type 'NSArray' in coercion
                var temp2 = self.array2 as NSArray
                            ~~~~~^

Are there restrictions on what can be converted to NSArray?

Doug Hill

On Jan 25, 2017, at 9:24 AM, Doug Hill via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Thanks for the help. I'm still trying to figure out how Swift works, particularly what the error messages mean. This has been driving me a little nuts trying to figure out what is wrong via sometimes cryptic errors. Also, it seems like getting generic programming working in Swift is more difficult than I'm used to (even than C++!) so this answer helps figure out how the compiler works.

Doug Hill

On Jan 23, 2017, at 7:04 PM, Zhao Xin <owenzx@gmail.com <mailto:owenzx@gmail.com>> wrote:

It seems to me that you didn't initialize your `myArray` before you casted it. That caused the problem.

Zhaoxin

On Tue, Jan 24, 2017 at 9:34 AM, Jon Shier via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
enumerateObjects(options:using:) exists on NSArray in Swift. And I was able to create your generic class just fine:

class Test<T> {
    var array: [T] = []
    
    init() {
        var temp = array as NSArray
    }
}


(Pierre Monod-Broca) #12

You should try:

class Test<T: NSObject> {
    let array: [T] = []
    . . .

Because when you declare `class Test<NSObject>`, NSObject is the generic parameter, no longer the class.

Pierre

···

Le 26 janv. 2017 à 02:45, Doug Hill via swift-users <swift-users@swift.org> a écrit :

Unfortunately, this is for a work-related project, not just research, so I'm looking for solutions to specific problems that I'll need for my work.

I guess I'll have to file this one away as broken in Swift 2.x

Doug

On Jan 25, 2017, at 5:28 PM, Zhao Xin <owenzx@gmail.com> wrote:

I think in swift 2.x, the `Array` is not mature enough to do a lot of things. Besides, `NSArray` can also hold non-NSObjects like Int, for example.

I suggest you to use the latest Swift to do your research. As in Swift, everything moves fast and changes a lot. In the latest Xcode beta, all swift 2.x are abandoned. The latest stable swift is 3.0.2 and 2.3. The next release will be swift 3.1.

Zhaoxin

On Thu, Jan 26, 2017 at 9:17 AM, Doug Hill <swiftusers@breaqz.com> wrote:
I'm guessing that conversion of a Swift array to an NSArray can only happen if the Swift array holds NSObjects. So, I tried changing the type parameter of my class to NSObject:

class Test<NSObject>
{
    let array = [NSObject]()

    init() {
        let temp = self.array as NSArray
    }
}

error: cannot convert value of type '[NSObject]' to type 'NSArray' in coercion
        var temp = self.array as NSArray
                    ~~~~~^~~~~

However, if I change the type parameter to something else it compiles with no problem.

class Test<T>
{
    let array = [NSObject]()

    init() {
        let temp = self.array as NSArray
    }
}

I guess this is interesting, but I still can't create an array with items whose type is the type parameter of the class and then convert to NSArray.

Doug Hill

On Jan 25, 2017, at 10:49 AM, Doug Hill <swiftusers@breaqz.com> wrote:

OK, I just tried testing this code in my app and a Swift playground. I also tried a variation on the initializer just for the heck of it. I get the following error:

class Test<T>
{
    var array:[T] = []
    var array2 = [T]()

    init() {
        var temp = self.array as NSArray
        var temp2 = self.array2 as NSArray
    }
}

error: cannot convert value of type '[T]' to type 'NSArray' in coercion
                var temp = self.array as NSArray
                           ~~~~~^
error: cannot convert value of type '[T]' to type 'NSArray' in coercion
                var temp2 = self.array2 as NSArray
                            ~~~~~^

Are there restrictions on what can be converted to NSArray?

Doug Hill

On Jan 25, 2017, at 9:24 AM, Doug Hill via swift-users <swift-users@swift.org> wrote:

Thanks for the help. I'm still trying to figure out how Swift works, particularly what the error messages mean. This has been driving me a little nuts trying to figure out what is wrong via sometimes cryptic errors. Also, it seems like getting generic programming working in Swift is more difficult than I'm used to (even than C++!) so this answer helps figure out how the compiler works.

Doug Hill

On Jan 23, 2017, at 7:04 PM, Zhao Xin <owenzx@gmail.com> wrote:

It seems to me that you didn't initialize your `myArray` before you casted it. That caused the problem.

Zhaoxin

On Tue, Jan 24, 2017 at 9:34 AM, Jon Shier via swift-users <swift-users@swift.org> wrote:
enumerateObjects(options:using:) exists on NSArray in Swift. And I was able to create your generic class just fine:

class Test<T> {
    var array: [T] = []
    
    init() {
        var temp = array as NSArray
    }
}

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Doug Hill) #13

Ah, thanks for the info about Swift syntax. I guess my C++ background trips me up on some of this Swift syntax.

Doug Hill

···

On Jan 25, 2017, at 11:32 PM, Pierre Monod-Broca <pierremonodbroca@gmail.com> wrote:

You should try:

class Test<T: NSObject> {
    let array: [T] = []
    . . .

Because when you declare `class Test<NSObject>`, NSObject is the generic parameter, no longer the class.

Pierre

Le 26 janv. 2017 à 02:45, Doug Hill via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> a écrit :

Unfortunately, this is for a work-related project, not just research, so I'm looking for solutions to specific problems that I'll need for my work.

I guess I'll have to file this one away as broken in Swift 2.x

Doug

On Jan 25, 2017, at 5:28 PM, Zhao Xin <owenzx@gmail.com <mailto:owenzx@gmail.com>> wrote:

I think in swift 2.x, the `Array` is not mature enough to do a lot of things. Besides, `NSArray` can also hold non-NSObjects like Int, for example.

I suggest you to use the latest Swift to do your research. As in Swift, everything moves fast and changes a lot. In the latest Xcode beta, all swift 2.x are abandoned. The latest stable swift is 3.0.2 and 2.3. The next release will be swift 3.1.

Zhaoxin

On Thu, Jan 26, 2017 at 9:17 AM, Doug Hill <swiftusers@breaqz.com <mailto:swiftusers@breaqz.com>> wrote:
I'm guessing that conversion of a Swift array to an NSArray can only happen if the Swift array holds NSObjects. So, I tried changing the type parameter of my class to NSObject:

class Test<NSObject>
{
    let array = [NSObject]()

    init() {
        let temp = self.array as NSArray
    }
}

error: cannot convert value of type '[NSObject]' to type 'NSArray' in coercion
        var temp = self.array as NSArray
                    ~~~~~^~~~~

However, if I change the type parameter to something else it compiles with no problem.

class Test<T>
{
    let array = [NSObject]()

    init() {
        let temp = self.array as NSArray
    }
}

I guess this is interesting, but I still can't create an array with items whose type is the type parameter of the class and then convert to NSArray.

Doug Hill

On Jan 25, 2017, at 10:49 AM, Doug Hill <swiftusers@breaqz.com <mailto:swiftusers@breaqz.com>> wrote:

OK, I just tried testing this code in my app and a Swift playground. I also tried a variation on the initializer just for the heck of it. I get the following error:

class Test<T>
{
    var array:[T] = []
    var array2 = [T]()

    init() {
        var temp = self.array as NSArray
        var temp2 = self.array2 as NSArray
    }
}

error: cannot convert value of type '[T]' to type 'NSArray' in coercion
                var temp = self.array as NSArray
                           ~~~~~^
error: cannot convert value of type '[T]' to type 'NSArray' in coercion
                var temp2 = self.array2 as NSArray
                            ~~~~~^

Are there restrictions on what can be converted to NSArray?

Doug Hill

On Jan 25, 2017, at 9:24 AM, Doug Hill via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Thanks for the help. I'm still trying to figure out how Swift works, particularly what the error messages mean. This has been driving me a little nuts trying to figure out what is wrong via sometimes cryptic errors. Also, it seems like getting generic programming working in Swift is more difficult than I'm used to (even than C++!) so this answer helps figure out how the compiler works.

Doug Hill

On Jan 23, 2017, at 7:04 PM, Zhao Xin <owenzx@gmail.com <mailto:owenzx@gmail.com>> wrote:

It seems to me that you didn't initialize your `myArray` before you casted it. That caused the problem.

Zhaoxin

On Tue, Jan 24, 2017 at 9:34 AM, Jon Shier via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
enumerateObjects(options:using:) exists on NSArray in Swift. And I was able to create your generic class just fine:

class Test<T> {
    var array: [T] = []
    
    init() {
        var temp = array as NSArray
    }
}

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users