[swift-evolution] [Proposal] Allow scoped properties from within computed properties
Joseph Newton
jnewto32 at gmail.com
Fri Jan 13 11:27:33 CST 2017
Hi,
I've done a lot of Objective-C and have been been a fan of Swift since it's
come out, however, there's a small feature of Objective-C that I would
really like to see implemented in Swift:
In Objective-C you have a few options implementation-wise when creating
properties for your class. You could use the *@synthesize *statement to
have the compiler create the backing ivar along with the appropriate
accessor methods or your could use the *@dynamic* statement to tell the
compiler that you're going to create your own accessor methods and backing
ivar (if needed).
Additionally, one could use the *@synthesize* statement to have the
compiler create the backing ivar, and then they could create custom
accessor methods to supply custom functionality or validation. I use this
third case extensively in my Objecitve-C code but there's not a concise way
of doing this in Swift.
For example, I might have an Objective-C implementation that looks like
this:
@interface Foo : NSObject
@property (nullable, copy) NSString *bar;
@end
@implementation Foo
@synthesize bar = _bar; // Creates ivar '_bar'
- (void)setBar:(NSString *)bar {
if (bar.length < 100)
_bar = nil;
else
_bar = [bar copy];
}
@end
Currently, the only way to implement this in Swift - AFAIK - is as follows:
class Foo {
private var _bar: String?
public var bar: String? {
get { return _bar }
set {
if (newValue?.characters.count ?? 0) < 100 {
_bar = nil
}
else {
_bar = newValue.copy() as! String
}
}
}
}
Although this works, it isn't exactly glamorous. The main drawback of this
implementation (unless intended) is that you now have any additional '_bar'
variable accessible within the scope of your class.
My proposal is to allow stored properties in the declaration block of
computed properties. For this example, the '_bar' declaration would simply
be moved inside of the declaration block for 'bar':
class Foo {
public var bar: String? {
var _bar: String?
get { return _bar }
set {
if (newValue?.characters.count ?? 0) < 100 {
_bar = nil
}
else {
_bar = newValue.copy() as! String
}
}
}
}
Only the getter and setter methods of 'bar' are allowed to access and
modify the stored '_bar' property. My proposal would also allow for
multiple stored properties of varying types within the scope of a single
computed property. This would also simply atomic synchronization for single
variables:
class Foo {
static var synchronizedBar: String? {
var queue = DispatchQueue(label: "Foo.synchronizedBar")
var bar: String?
get { return queue.sync { return bar } }
set { queue.sync { bar = newValue } }
}
}
Are there any suggestions or arguments, for or against, for this proposal?
-- Joe Newton
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170113/77f9e00f/attachment.html>
More information about the swift-evolution
mailing list