<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">The issue is that when the method doesn't immediately use the values of the array (e.g. stores it for later, or even worse passes them on to another object), the crash appears much later in the program with a message that NSNull doesn't respond to some selector - and that's often hard to debug.<div class=""><br class=""></div><div class="">On the other hand, I agree that it's better to use NSNull than how it currently works since this is a valid Swift 3 code:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 9px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> arr: [</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span><span style="font-variant-ligatures: no-common-ligatures" class="">?] = [</span><span style="font-variant-ligatures: no-common-ligatures; color: #d12f1b" class="">"Hello"</span><span style="font-variant-ligatures: no-common-ligatures" class="">, </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">nil</span><span style="font-variant-ligatures: no-common-ligatures" class="">]</span></div><div style="margin: 0px; font-size: 9px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">NSArray</span><span style="font-variant-ligatures: no-common-ligatures" class="">(array: </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">arr</span><span style="font-variant-ligatures: no-common-ligatures" class="">)</span></div><div class=""><br class=""></div><div class="">that will not crash and will produce a valid NSArray. As Douglas Gregor mentioned earlier:</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class="">[…] because any Swift type can be placed in an Any, and anything can be bridged to Objective-C. Nearly all of the concerns in this thread are about this aspect of the already-accepted-and-implemented SE-0116: that an optional can get passed through to an Objective-C ‘id’ without being explicitly unwrapped. That behavior exists, and the type of the object seen in Objective-C is an <b class="">opaque Swift wrapper type</b>. <br class=""></blockquote><div class=""><br class=""></div><div class="">Playground will show the NSArray as two NSObjects (which are in fact _SwiftValue), which means that the ObjC will crash as well, but with even a more obscure message:</div><div class=""><br class=""></div><div class=""><div class="">Attempted to dereference an invalid ObjC Object or send it an unrecognized selector.</div></div><div class=""><br class=""></div><div class="">So, choosing between two evils, I personally vote +1 for adding the NSNull bridging...</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Sep 3, 2016, at 10:01 AM, Pyry Jahkola via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">I don't feel confident enough about the Swift–Obj-C interop to cast my own vote but I'd like to question this sentiment:</div><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 03 Sep 2016, at 03:17, Charles Srstka via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="font-family: Menlo-Regular; font-size: 11px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">With the existing behavior, such mistakes are immediately obvious as Objective-C receives an opaque object that it cannot use (and probably soon crashes), so they are unlikely to make it past QA testing.</span></div></blockquote></div><br class="">
How is this different with NSNull though? If the callee expects an array of NSNumbers for example and uses them (for anything more specific than NSObject), the first NSNull instance will throw an NSInvalidArgumentException basically crashing the program as well:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Menlo" class=""><b class="">$ cat example.m</b></font></div><div class=""><font face="Menlo" class="">@import Foundation;</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">int main() {</font></div><div class=""><font face="Menlo" class=""> id number = NSNull.null;</font></div><div class=""><font face="Menlo" class=""> NSLog(@"%ld", [number integerValue]);</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><div class=""><font face="Menlo" class=""><b class="">$ clang -fmodules example.m -o example && ./example</b></font></div></div><div class=""><div class=""><font face="Menlo" class="">2016-09-03 10:47:21.822 example[31488:151700] -[NSNull integerValue]: unrecognized selector sent to instance 0x7fff78561780</font></div></div><div class=""><div class=""><span style="font-family: Menlo;" class="">(snip...)</span></div></div><div class=""><div class=""><font face="Menlo" class="">libc++abi.dylib: terminating with uncaught exception of type NSException</font></div></div><div class=""><div class=""><font face="Menlo" class="">Abort trap: 6</font></div></div></blockquote><div class=""><div class=""><br class=""></div><div class="">OTOH, if the only thing the Obj-C code planned to do was immediately convert the NSArray into JSON, then a previously crashing example would now start producing a JSON array with mixed numbers and nulls. But is that kind of code likely in practice?</div></div><div class=""><br class=""></div><div class="">It would be different though if NSNull just swallowed any messages it receives like `nil` does. <a href="https://github.com/jspahrsummers/libextobjc/blob/master/extobjc/EXTNil.h" class="">There are 3rd party examples</a> of that behaviour, and <i class="">that</i> would be detrimental to code quality in the case of Swift interop.</div><div class=""><br class=""></div><div class="">— Pyry</div><div class=""><br class=""></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></div></div></div></body></html>