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
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to