Swift protocol-typed property causes didSet recursion
| Originator: | dwineman | ||
| Number: | rdar://22220340 | Date Originated: | 10-Aug-2015 03:18 PM |
| Status: | Duplicate/22953072 | Resolved: | Yes (in 7.2 beta) |
| Product: | Developer Tools | Product Version: | Xcode 7.0 beta 5 (7A176x) |
| Classification: | Serious Bug | Reproducible: | Always |
Summary:
In Swift 2.0, when a protocol-typed property has a didSet observer, and didSet calls a method that accesses a field of that property — not mutates, just accesses — didSet will be called recursively until the stack overflows and the app crashes.
Steps to Reproduce:
Set up the following scenario in code:
1. Create a non-objc protocol Foo with at least one {get} property (call it ‘x’).
2. Create a class Bar that has a property whose type is the protocol (call it ‘p’).
3. In Bar.p’s didSet, call some instance method.
4. In the instance method body, access p.x (don’t assign to it, just pass its value to print() or something).
5. Initialize an instance of Bar and assign to its ‘p’ field an instance of any class that conforms to Foo.
Expected Results:
Nothing special.
Actual Results:
Bar.p’s didSet observer, the instance method, and an internal closure called “materializeForSet” are called in unbounded recursion until the program crashes with EXC_BAD_ACCESS.
Regression:
Issue observed in all betas of Xcode 7 / Swift 2.0 (but I didn’t manage to narrow down the cause until now).
Notes:
Making any of the following changes to the provided sample project prevents the bug from occurring:
* Tag protocol Foo with @objc and/or “class”
* Make Foo.x a {get set} property instead of just {get}
* Make Bar a struct instead of a class
* In the kablam() method, assign p to a temp var before accessing p.x (this alternative is provided and commented out)
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!
Closed as duplicate of rdar://22953072.
Appears to be fixed in Xcode 7.2 beta 2 (7C46t). I'm guessing this was related to rdar://22953072, which is listed as resolved in the release notes.
Also submitted 22685592
22685592 also submitted to Apple
Sample project link
https://www.dropbox.com/s/0a7dbzd6aagwgk8/DidSet.zip?dl=0