[swift-users] Weak references in generic types

Karl Wagner razielim at gmail.com
Thu Sep 8 08:28:25 CDT 2016


  
  
What I'm trying to say is that P is a protocol and not a class, so it does not conform to AnyObject.   P does not conform to P.
  

  
It is in some sense a language limitation that we cant express what you're talking about. If we weren't using mailing lists it would be easier to search for "protocol self-conformance" on swift-evo and to read the earlier discussion about it.   
  
    
  

  
  
>   
> On Sep 2, 2016 at 1:04 am,  <Howard Lovatt (mailto:howard.lovatt at gmail.com)>  wrote:
>   
>   
> @Karl,  
>
>   
> You say "In the second example, you’re creating WeakReference<P>. P does not conform to P or to AnyObject.", but P does conform to AnyObject.
>   
>
>   
> I suspect it is a compiler limitation/ bug.   
>   
>
>   
>   -- Howard.   
>
>  On Thursday, 1 September 2016, Karl  <razielim at gmail.com (mailto:razielim at gmail.com)>  wrote:
>   
> >   
> >
> >   
> >   
> > >   
> > > On 1 Sep 2016, at 03:23, Howard Lovatt via swift-users  <swift-users at swift.org (javascript:_e(%7B%7D,'cvml','swift-users at swift.org');)>  wrote:
> > >   
> > >   
> > >   
> > > Playing around I found that if you make the protocol @objc instead of AnyObject then it works :). EG:  
> > >
> > >   
> > > >   
> > > > struct WeakReference<T: AnyObject>  {
> > > >   
> > > >        weak var value: T?
> > > >   
> > > > }
> > > >   
> > > > @objc protocol P { // Note @objc, class or AnyObject does not work
> > > >   
> > > >        var i: Int { get }
> > > >   
> > > > }
> > > >   
> > > > class CP: P {
> > > >   
> > > >        var i: Int = 0
> > > >   
> > > > }
> > > >   
> > > > let weakPs: [WeakReference<P>] = [WeakReference(value: cP)] // Note typed as `[WeakReference<P>]`
> > > >   
> > > > print("P: \(weakPs[0].value!.i)") // 0
> > > >   
> > >   
> > >   
> > >
> > > Not a 'pure' Swift solution :(, but OK in my case.
> > >
> > >   
> > >   
> > >   
> > >
> > >   
> > >   
> > >    -- Howard.
> > >     
> > >   
> > > On 29 August 2016 at 16:21, Howard Lovatt  <howard.lovatt at gmail.com (javascript:_e(%7B%7D,'cvml','howard.lovatt at gmail.com');)>  wrote:
> > >   
> > > >   
> > > > Hi,  
> > > >
> > > >   
> > > > I am wanting to use weak references in generic data structures; in the example below Array, but in general any generic type. I can almost get it to work :(
> > > >   
> > > >
> > > >   
> > > > My experiments started off well; the following works:
> > > >   
> > > >
> > > >   
> > > > >   
> > > > > // Array of weak references OK
> > > > >   
> > > > > struct WeakReference<T: AnyObject>  {
> > > > >   
> > > > >        weak var value: T?
> > > > >   
> > > > > }
> > > > >   
> > > > > class C {
> > > > >   
> > > > >        var i: Int = 0
> > > > >   
> > > > > }
> > > > >   
> > > > > let c = C() // Strong reference to prevent collection
> > > > >   
> > > > > let weakCs = [WeakReference(value: c)] // OK
> > > > >   
> > > > > print("C: \(weakCs[0].value!.i)") // 0
> > > > >   
> > > >   
> > > >  I can add a protocol:  
> > > >
> > > >   
> > > > >   
> > > > > // Array of weak references that implements a protocol OK
> > > > >   
> > > > > protocol P: AnyObject { // Note AnyObject
> > > > >   
> > > > >        var i: Int { get }
> > > > >   
> > > > > }
> > > > >   
> > > > > class CP: P {
> > > > >   
> > > > >        var i: Int = 0
> > > > >   
> > > > > }
> > > > >   
> > > > > let cP = CP() // Strong reference to prevent collection
> > > > >   
> > > > > let weakCPs = [WeakReference(value: cP)] // OK
> > > > >   
> > > > > print("CP: \(weakCPs[0].value!.i)") // 0
> > > > >   
> > > >   
> > > >   
> > > >
> > > >   
> > > > But when I want an array of weak references to the protocol I get an error:
> > > >   
> > > >
> > > >     
> > > > >   
> > > > > // Array of weak references of a protocol not OK
> > > > >   
> > > > > let weakPs: [WeakReference<P>] = [WeakReference(value: cP)] // Using 'P' as a concrete type conforming to protocol 'AnyObject' is not supported
> > > > >   
> > > > > print("P: \(weakPs[0].value!.i)") // 0
> > > > >   
> > > >   
> > > >   
> > > >
> > > >   
> > > > Is there something I have missed?
> > > >   
> > > >
> > > >   
> > > > The error message, "Using 'P' as a concrete type conforming to protocol 'AnyObject' is not supported", implies that it is a temporary limitation of the compiler; is this going to be fixed? Should I lodge a bug report?
> > > >   
> > > >
> > > >   
> > > > Thanks in advance for any advice,
> > > >   
> > > >
> > > >   
> > > >   
> > > >    -- Howard.
> > > >               
> > >  _______________________________________________
> > >  swift-users mailing list
> > >   swift-users at swift.org (javascript:_e(%7B%7D,'cvml','swift-users at swift.org');)
> > >   https://lists.swift.org/mailman/listinfo/swift-users
> > >         
> >   
> > Your problem is protocol self-conformance. In the first example, you’re creating WeakReference<CP>. CP conforms to P and to AnyObject. In the second example, you’re creating WeakReference<P>. P does not conform to P or to AnyObject.
> >   
> >
> >   
> > As for why @objc fixes it? … ¯\_(ツ)_/¯ all bets are off whenever @objc gets involved in anything.
> >   
> >
> >   
> > Karl
> >   
> >   
>   
>   
>   
>  --
>  -- Howard.
>        
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160908/8ef9fbb0/attachment.html>


More information about the swift-users mailing list