diff --git a/src/foundation.jl b/src/foundation.jl index 9a58a4a..4205165 100644 --- a/src/foundation.jl +++ b/src/foundation.jl @@ -179,9 +179,12 @@ end NSArray() = NSArray(@objc [NSArray array]::id{NSArray}) -function NSArray(elements::Vector) - arr = @objc [NSArray arrayWithObjects:elements::Ptr{id{Object}} - count:length(elements)::NSUInteger]::id{NSArray} +function NSArray(elements::Vector{<:NSObject}) + arr = GC.@preserve elements begin + pointers = [element.ptr for element in elements] + @objc [NSArray arrayWithObjects:pointers::id{Object} + count:length(elements)::NSUInteger]::id{NSArray} + end return NSArray(arr) end diff --git a/src/syntax.jl b/src/syntax.jl index 8d2cc65..54c7bfb 100644 --- a/src/syntax.jl +++ b/src/syntax.jl @@ -269,8 +269,6 @@ macro objcwrapper(ex...) ex = quote $(ex.args...) - Base.unsafe_convert(T::Type{<:id}, dev::$instance) = convert(T, dev.ptr) - # add a pseudo constructor to the abstract type that also checks for nil pointers. function $name(ptr::id) ptr == nil && throw(UndefRefError()) @@ -283,14 +281,25 @@ macro objcwrapper(ex...) ex = quote $(ex.args...) - Base.:(==)(a::$instance, b::$instance) = a.ptr == b.ptr - Base.hash(dev::$instance, h::UInt) = hash(dev.ptr, h) + Base.:(==)(a::$instance, b::$instance) = pointer(a) == pointer(b) + Base.hash(obj::$instance, h::UInt) = hash(pointer(obj), h) end end esc(ex) end +Base.pointer(obj::Object) = obj.ptr + +# when passing a single object, we automatically convert it to a pointer +Base.unsafe_convert(T::Type{<:id}, obj::Object) = convert(T, pointer(obj)) + +# in the case of a vector of objects, we expect the caller to have converted them +# XXX: it's too bad `cconvert` cannot do the `[pointer(obj) for obj in objs]` for us +# (because we can only derive unsafe references in `unsafe_convert`) +Base.unsafe_convert(T::Type{<:id}, ptrs::Vector{<:id}) = + reinterpret(T, pointer(ptrs)) + # Property Accesors diff --git a/test/runtests.jl b/test/runtests.jl index 8bbce50..65e0ec9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -143,6 +143,8 @@ end @test reinterpret(NSString, arr2[1]) == "Hello" @test reinterpret(NSString, arr2[2]) == "World" @test Vector{NSString}(arr2) == arr1 + + @test_throws MethodError NSArray([NSUInteger(42)]) end @testset "NSDictionary" begin