> On Apr 30, 2017, at 4:43 PM, Brent Royal-Gordon <br...@architechies.com> 
> wrote:
> 
>> On Apr 30, 2017, at 11:57 AM, Charles Srstka via swift-users 
>> <swift-users@swift.org> wrote:
>> 
>> What does the community think? Should I file this as a bug on Swift? 
>> Foundation? AppKit? All three?
> 
> I would file it against AppKit. Once it's in Radar, they can kick the can 
> over to Foundation or Swift, but it's trickier to do the opposite.

Thought about it a bit, and it really is two separate issues. AppKit probably 
*shouldn’t* be using NSCopyObject to copy things, and Swift shouldn’t be 
crashing if it does. So, I’ve filed a bug report on each:

rdar://31912100
https://bugs.swift.org/browse/SR-4756 <https://bugs.swift.org/browse/SR-4756>

In the event that anyone with the same problem (which, if anyone’s curious, was 
implementing a custom field editor, the only customization point for which is 
on NSCell rather than NSControl) discovers this thread, let me save you a 
little time on some workarounds that don’t work:

Implementing your own copy(with:) method fails, because you need to call 
super’s implementation to copy the cell effectively, and the crash will still 
occur.

Using a weak property to the containing NSControl and putting your stored 
properties there doesn't work, because NSCopyObject doesn't seem to play nice 
with weak variables either, and all sorts of errors will be logged to the 
console.

Using an unowned property to the containing NSControl doesn't work, because 
unowned properties cannot be null, and the connection will not be made until 
runtime.

Making a non-Objective-C property and storing your Objective-C properties 
inside it seemed to work some of the time, and crashed other times, when I 
tried it. I haven’t studied the low-level layout of Swift objects enough to 
know why this was.

What works is to use Objective-C associated objects. Use 
objc_getAssociatedObject in the getter and objc_setAssociatedObject in the 
setter. Be sure to use withUnsafeMutableBytes on your key property and pass its 
baseAddress as the key, because the associated object functions take immutable 
pointers, and since your key property has to be a var to ensure it stays 
unique, just passing it via & character will cause Swift to make an immutable 
copy first, and then pass a pointer to *that*, and things won’t work.

Charles

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

Reply via email to