Re: Assigning an element of a swift array to a userdata parameter triggers didSet

2015-11-18 Thread John McCall
> On Nov 18, 2015, at 11:12 AM, Quincey Morris 
>  wrote:
> On Nov 18, 2015, at 10:57 , Jens Alfke  wrote:
>> 
>> Doesn’t the pointer become invalid as soon as myElement goes out of scope? 
>> (There’s a reason that type is called *Unsafe*Pointer…)
> 
> Yes, but so does &myArray[0] in the original code. According to your 
> hypothesis, it’s copied into a temporary, which also becomes invalid as soon 
> as the current scope ends.

It’s actually shorter than that; inout temporaries are valid just for the 
duration of the call.

Going back to your actual problem: “user data” parameters like this are really 
just pointer-sized opaque buckets of bits.  Assuming your array is, in fact, 
stably-indexed (and if it isn’t, passing a pointer won’t work either!), 
consider just passing an index as the user data; you can construct a pointer 
from an Int like this:
  UnsafePointer(bitPattern: i)
and get the Int back like this:
  unsafeBitCast(ptr, Int.self)

The fact that the latter is apparently the only interface for getting back to 
an Int is probably a bug.

John.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Assigning an element of a swift array to a userdata parameter triggers didSet

2015-11-18 Thread Charles Srstka
> On Nov 18, 2015, at 7:24 AM, Eric Gorr  > wrote:
> 
> Yes, that all makes sense. So, the question is what can I do about it? The 
> number of tooltips I need is the same number of elements in the array and the 
> number of elements in the array can change over the lifetime of the 
> application. So, it is natural to store the information needed by the tooltip 
> inside of an array and pass a pointer to an array element as the userdata for 
> the tooltip. If my current implementation is not going to work, what is the 
> recommended implementation for this kind of behavior?

How about creating a context object or struct, with a single property to which 
you assign a copy of the array (or, alternatively, a computed property that 
dynamically returns the contents of the array)? Then you’re not making an 
UnsafePointer of the array itself, and it probably shouldn’t get unnecessarily 
assigned to.

Charles

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Assigning an element of a swift array to a userdata parameter triggers didSet

2015-11-18 Thread Quincey Morris
On Nov 18, 2015, at 10:57 , Jens Alfke  wrote:
> 
> Doesn’t the pointer become invalid as soon as myElement goes out of scope? 
> (There’s a reason that type is called *Unsafe*Pointer…)

Yes, but so does &myArray[0] in the original code. According to your 
hypothesis, it’s copied into a temporary, which also becomes invalid as soon as 
the current scope ends.

(I didn’t check the docs to see if the void* parameter to addToolTipRect needs 
a longer lifetime. If it does, then there’s manual memory management to do, 
regardless of what approach is taken. That’s why there ought to be a better 
API.)

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Assigning an element of a swift array to a userdata parameter triggers didSet

2015-11-18 Thread Jens Alfke

> On Nov 18, 2015, at 10:17 AM, Quincey Morris 
>  wrote:
> 
> If the array element (a dictionary, in your original post) is small enough, 
> you can pass a pointer to a copy of the element instead of a pointer to the 
> element. That is:
> 
>   var myElement = myArray[0]
>   view.addToolTipRect( NSMakeRect( 0, 0, 100, 100), owner: self, 
> userData: &myElement )

Doesn’t the pointer become invalid as soon as myElement goes out of scope? 
(There’s a reason that type is called *Unsafe*Pointer…)

—Jens
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Assigning an element of a swift array to a userdata parameter triggers didSet

2015-11-18 Thread Quincey Morris
On Nov 18, 2015, at 05:24 , Eric Gorr  wrote:
> 
> Yes, that all makes sense. So, the question is what can I do about it? The 
> number of tooltips I need is the same number of elements in the array and the 
> number of elements in the array can change over the lifetime of the 
> application. So, it is natural to store the information needed by the tooltip 
> inside of an array and pass a pointer to an array element as the userdata for 
> the tooltip. If my current implementation is not going to work, what is the 
> recommended implementation for this kind of behavior?

If the array element (a dictionary, in your original post) is small enough, you 
can pass a pointer to a copy of the element instead of a pointer to the 
element. That is:

var myElement = myArray[0]
view.addToolTipRect( NSMakeRect( 0, 0, 100, 100), owner: self, 
userData: &myElement )

If you don’t want to make a copy of the element, the best approach is to make 
the array elements reference types rather than value types. (You could use 
NSDictionary, for example.) Swift makes it so easy to use value types, it’s 
hard to remember that the old Obj-C way of doing things is sometimes better.

You should probably also submit a bug report about the NSView tool tip APIs. 
There ought to be a better way in Swift than using unmanaged memory pointers. 
They have potential memory management issues for ARC, too.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Assigning an element of a swift array to a userdata parameter triggers didSet

2015-11-18 Thread Eric Gorr
Yes, that all makes sense. So, the question is what can I do about it? The 
number of tooltips I need is the same number of elements in the array and the 
number of elements in the array can change over the lifetime of the 
application. So, it is natural to store the information needed by the tooltip 
inside of an array and pass a pointer to an array element as the userdata for 
the tooltip. If my current implementation is not going to work, what is the 
recommended implementation for this kind of behavior?

I do have this simple test project at: 
https://github.com/ericgorr/tooltip_arrays 



> On Nov 17, 2015, at 9:48 PM, Jens Alfke  wrote:
> 
> I think the cause is “&(myArray[0])”. In Swift it isn't possible to get a 
> pointer to an array item — these aren’t C arrays, their internal 
> representation is opaque! So what I think happens is that it copies 
> myArray[0] into a temporary and creates an UnsafeMutablePointer to that. 
> Then, after the call, it assumes that the call might have mutated that 
> temporary, so it stores it back into myArray.
> 
> Then, mutating myArray is logically equivalent to copying it, modifying the 
> copy, and storing the copy back into the property. (Apparently it’s often 
> optimized, fortunately, but those are the semantics.) Which means that your 
> ‘didSet’ handler gets called.
> 
> —Jens

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Assigning an element of a swift array to a userdata parameter triggers didSet

2015-11-17 Thread Jens Alfke
I think the cause is “&(myArray[0])”. In Swift it isn't possible to get a 
pointer to an array item — these aren’t C arrays, their internal representation 
is opaque! So what I think happens is that it copies myArray[0] into a 
temporary and creates an UnsafeMutablePointer to that. Then, after the call, it 
assumes that the call might have mutated that temporary, so it stores it back 
into myArray.

Then, mutating myArray is logically equivalent to copying it, modifying the 
copy, and storing the copy back into the property. (Apparently it’s often 
optimized, fortunately, but those are the semantics.) Which means that your 
‘didSet’ handler gets called.

—Jens
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com