Unexpected Xcode 9.3 beta 4 breaking ObjC/Swift change?

https://github.com/apple/swift/pull/11744 made it a warning to specify `weak` on Swift properties (vars) in protocols. This is present in Xcode 9.3 beta 4. In other words this now generates a warning:


protocol MyProtocol {
    // 'weak' should not be applied to a property declaration in a protocol and will be disallowed in future versions
    weak var delegate: MyDelegate?
}


Instead, weak is omitted from the protocol declaration, and Swift implementions of this protocol can redeclare the property as weak themselves:


class Impl: MyProtocol {
    weak var delegate: MyDelegate?
}


However, this is a problem for ObjC implementations since the compiler complains if you redeclare the property and change the strong/weakness:


#import <MyFramework-Swift.h>

@interface ImplObjC : NSObject <MyProtocol>

// warning: 'retain (or strong)' attribute on property 'delegate' does not match the property inherited from 'MyProtocol' [-Wproperty-attribute-mismatch]
@property (nonatomic, weak, nullable) id<MyDelegate> delegate;

@end


Alternatively in a private category:


@interface ImplObjC ()
// error: illegal redeclaration of property in class extension 'ImplObjC' (attribute must be 'readwrite', while its primary must be 'readonly')
@property (nonatomic, weak, nullable) id<MyDelegate> delegate;

@end


Alternatively synthesizing into a different ivar with __weak:


@interface ImplObjC ()
{
    // error: existing instance variable 'm_delegate' for strong property 'delegate' may not be __weak
    __weak id<MyDelegate> m_delegate;
}
@end

@implementation ImplObjC

@synthesize delegate = m_delegate;

@end


The only alternative that works is to override the setter and getter for the weak property and back it with a strong ivar/property. This is ugly and tedious however.


We build with "warnings as errors" for ObjC, so this is a source breaking change for our existing code. It doesn't seem like it would be a good idea to ignore the Wproperty-attribute-mismatch warning. This is a problem for any existing ObjC code that implements Swift protocols like this.


Now, there are legitimate design discussions to be had over whether a delegate property belongs on an abstract protocol, but given how common the (weak) delegate pattern is in ObjC I believe there will be a significant amount of this kind of code in the wild (we ran into this at least).


Is this a known/expected issue?

I’ve approved your post here but I agree with QuinceyMorris that your Swift Forums thread is a better place to talk about this issue.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Unexpected Xcode 9.3 beta 4 breaking ObjC/Swift change?
 
 
Q