[swift-evolution] Should Swift apply "statement scope" for ARC

Michael Gottesman mgottesman at apple.com
Sat Sep 24 22:07:41 CDT 2016


> On Sep 23, 2016, at 3:29 PM, John Holdsworth <mac at johnholdsworth.com> wrote:
> 
> Sorry, I’m being a little slow on the uptake here. So in future optimised Swift the
> scope of a variable continuing an object doesn't determine it’s lifetime at all!
> That seems quite a departure.
> 
> This means you have to be very careful with contained UnsafePointers indeed.
> I got as far as needing to do:
> 
>     init(imageProducer:ImageProducer) {
>         withExtendedLifetime(CanvasBase()) {
>             super.init(javaObject: $0.javaObject)
>         }
>         image = createImage(imageProducer)
>     }
> 
> ..but the compiler was having none of it.

What was the error? I am assuming that super.init was not in the same function?

> For now the rigorous alternative is:
> 
>     init(imageProducer:ImageProducer) {
>         var locals = [jobject]()
>         super.init(javaObject: CanvasBase().localJavaObject(&locals))
>         JNI.DeleteLocalRef(locals[0])
>         image = createImage(imageProducer)
>     }
> 
> Some option to reinstate "strong-ness" of a var could be a more flexible alternative to
> “withExtendedLifetime” for my particular use case.
> 
>     init(imageProducer:ImageProducer) {
>         @strong var canvas = CanvasBase()
>         super.init(javaObject: canvas.javaObject)
>         image = createImage(imageProducer)
>     }
> 
> John
>   
>> On 23 Sep 2016, at 02:45, Joe Groff <jgroff at apple.com <mailto:jgroff at apple.com>> wrote:
>> 
>> 
>>> On Sep 22, 2016, at 5:13 PM, John Holdsworth <mac at johnholdsworth.com <mailto:mac at johnholdsworth.com>> wrote:
>>> 
>>> 
>>>> On 22 Sep 2016, at 23:57, Michael Gottesman <mgottesman at apple.com <mailto:mgottesman at apple.com>> wrote:
>>>> 
>>>>> As a result the following transfer of a Java instance always worked:
>>>>> 
>>>>>    init(imageProducer:ImageProducer) {
>>>>>        let supr = CanvasBase()
>>>>>        super.init( javaObject: supr.javaObject )
>>>>>        image = createImage(imageProducer)
>>>>>    }
>>>>> 
>>>>> But the following only worked for debug compiles:
>>>>> 
>>>>>    init(imageProducer:ImageProducer) {
>>>>>        super.init( javaObject: CanvasBase().javaObject )
>>>>>        image = createImage(imageProducer)
>>>>>    }
>>>>> 
>>>>> Felt like a bit of a bear trap is all. Statement scope would avoid problems like this.
>>>> 
>>>> You are thinking about this the inverse way. That the first case works is an artifact of the optimizer failing to do a good enough job. Future improved ARC optimization can cause both to fail.
>>> 
>>> Were this the case I think it would be a step in the wrong direction. Swift is getting
>>> very eager at deallocating objects hence all the "withXYZ()" methods of late which
>>> seem like noise to me. Certainly, having something perform differently from debug
>>> to release builds was not a feature! Viva la Statement Scope which solves all this.
>> 
>> Statement scope is a brittle solution these problems. There's no shortage of C++ code that ends up subtly broken when it's refactored and ends up breaking due to hidden dependencies on statement scope. The precise lifetime semantics of C++ also prevent practically any optimization of nontrivial types without the explicit blessing of a handful of special cases like NRVO.
>> 
>> -Joe
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160924/badd20f7/attachment.html>


More information about the swift-evolution mailing list