qiubit
(Paweł Goliński)
1
Hey everyone,
I'm playing with using Apple's legacy types with Swift and discovered an interesting conundrum:
- At some point in my code I'm using API which provides me with
CFArray. I use it as follows:
let attachments: NSArray! =
CMSampleBufferGetSampleAttachmentsArray(
sampleBuffer!,
createIfNecessary: true
)
- Now, I happen to know that first element of this
CFArray is a CFMutableDictionary. I modify it as follows:
let dictionary = unsafeBitCast(CFArrayGetValueAtIndex(attachments, 0),
to: CFMutableDictionary.self)
let key = Unmanaged.passUnretained(
kCMSampleAttachmentKey_DisplayImmediately).toOpaque()
let value = Unmanaged.passUnretained(kCFBooleanTrue).toOpaque()
CFDictionarySetValue(dictionary, key, value)
- For debugging purposes, I created the following variables after the modification:
var isItNsMutableDictionary = attachments[0] is NSMutableDictionary
var maybeNsMutableDictionary = attachments[0] as? NSMutableDictionary
var nsMutableDictionary = maybeNsMutableDictionary!
var nsMutableDictionaryForcedDowncast =
attachments[0] as! NSMutableDictionary
- I attached debugger to look at variables. Here is what it said:
(lldb) po isItNsMutableDictionary
true
(lldb) po maybeNsMutableDictionary
▿ Optional<NSMutableDictionary>
▿ some : 1 element
▿ 0 : 2 elements
- key : DisplayImmediately
- value : 1
(lldb) po nsMutableDictionary
▿ 1 element
▿ 0 : 2 elements
- key : DisplayImmediately
- value : 1
(lldb) po nsMutableDictionaryForcedDowncast
<uninitialized>
What's going on there?
- Why is
nsMutableDictionaryForcedDowncast different then nsMutableDictionary?
- I expected
(a as? NSMutableDictionary)! to be the same as a as! NSMutableDictionary
- What could be the reason
as? works correctly when as! don't? Which one should I use?
The <uninitialized> makes it seem like you are stopped at a breakpoint on the fourth line (or you have optimizations turned on). If that's not the case, it could be a bug in LLDB and not the compiler/runtime.
What happens if you print the values instead of inspecting them in the debugger?
Could you file a bug report on bugs.swift.org with a self-contained example and reproduction steps?
- I expected
(a as? NSMutableDictionary)! to be the same as a as! NSMutableDictionary
This is correct, they should be the same according to the dynamic casting documentation:
The following invariants relate the three casting operators:
- [...]
- [...]
- Forced cast:
x as! T is equivalent to (x as? T)!
1 Like
qiubit
(Paweł Goliński)
3
Printing the value actually crashes the program with bad access exception.
I'll try to report this when I have time, good to know it can indeed be a Swift bug.