[swift-evolution] [Mini-proposal] Require @nonobjc on members of @objc protocol extensions

Douglas Gregor dgregor at apple.com
Tue Jan 5 11:40:03 CST 2016


> On Jan 5, 2016, at 3:51 AM, Andrey Tarantsov <andrey at tarantsov.com> wrote:
> 
> I'm against this, because I often write extensions on Apple classes (like, say, UIColor) that are only intended to be used from Swift, in a pure-Swift project, and I need no stinking' @nonobjc in there.

You are misreading my proposal. I’m not proposing to change anything about how extensions of classes work. Your extensions of UIColor and other Objective-C classes remain unchanged.

How many Apple *protocols*, such as delegates, have you extended? I expect it’s not that many.

> 
> How much of a problem can this surprise be? You call a method, the compiler tells you it's not there, you look up the reason, no harm done.

I’ve seen enough bugs filed and general confusion about this that the answer is “it’s quite a bit of a surprise”. The common case seems to be that people write a protocol extension of a delegate that implements some of its optional members. The only calls to that method occur in some framework code written in Objective-C, so there place for the compiler to tell you it’s not there.

	- Doug

> 
> A.
> 
> 
> 
>> On Jan 5, 2016, at 11:32 AM, Douglas Gregor via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>> Hi all,
>> 
>> We currently have a bit of a surprise when one extends an @objc protocol:
>> 
>> @objc protocol P { }
>> 
>> extension P {
>>   func bar() { }
>> }
>> 
>> class C : NSObject { }
>> 
>> let c = C()
>> print(c.respondsToSelector("bar")) // prints "false"
>> 
>> because the members of the extension are not exposed to the Objective-C runtime. 
>> 
>> There is no direct way to implement Objective-C entry points for protocol extensions. One would effectively have to install a category on every Objective-C root class [*] with the default implementation or somehow intercept all of the operations that might involve that selector. 
>> 
>> Alternately, and more simply, we could require @nonobjc on members of @objc protocol extensions, as an explicit indicator that the member is not exposed to Objective-C. It’ll eliminate surprise and, should we ever find both the mechanism and motivation to make default implementations of @objc protocol extension members work, we could easily remove the restriction at that time.
>> 
>> 	- Doug
>> 
>> [*] Assuming you can enumerate them, although NSObject and the hidden SwiftObject cover the 99%. Even so, that it’s correct either, because the root class itself might default such a method, and the category version would conflict with it, so...
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

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


More information about the swift-evolution mailing list