Swift class member access control
| Originator: | brent | ||
| Number: | rdar://17136480 | Date Originated: | 2014-6-03 |
| Status: | Duplicate/15747445 | Resolved: | |
| Product: | Developer Tools | Product Version: | Xcode 6A215l, swift-600.0.34.4.5 |
| Classification: | New Feature | Reproducible: | Always |
Summary:
Swift does not currently support access control. gparker stated on the developer forums that this support would be forthcoming, but I'd like to explain what I want from it, because I think the traditional public/protected/private model doesn't really cut the mustard.
One of the nice things about Objective-C is that its use of headers allows for many gradations between "private" and "public". Witness, for instance, UIGestureRecognizerSubclass.h in iOS, which contains methods that should only ever be used by subclasses, not ordinary users of the class. In Objective-C, it's possible to have not only private or protected interfaces, but even interfaces that are private between a small set of classes—for instance, a database manager class and the model classes it manages, or a small-but-user-expandable set of classes which need to interact with the class in a unique way.
I'd like to see that sort of flexibility in Swift. Here's how I suggest you do it.
The keyword should, I think, be "restricted". (I'm not married to that, but I like it better than "private".) It should be possible to restrict a method or property to just your own class, or to share it with a group of self-nominated classes; a fixed set of classes might be a sensible option as well. Some examples:
class MyClass {
// visible to anyone
var foo: String
func doFoo() {}
// only visible to MyClass (and maybe subclasses)
restricted var bar: String
restricted func doBar() {}
// restricted to classes in a certain permission group
permission BazClasses;
restricted(BazClasses) var baz: String
restricted(BazClasses) func doBaz() {}
// Optional: restricted to specific, enumerated classes
restricted(AnotherClass, AThirdClass) var quux: String
restricted(AnotherClass, AThirdClass) func doQuux()
}
Any class can gain access to the BazClasses group by saying something like:
class AnotherClass {
permitted MyClass.BazClasses
}
It may make sense to make some of these things into @annotations; I'm not exactly sure how those fit into Swift's design.
Steps to Reproduce:
1. Create a class in an Xcode playground.
2. Try to create a property or method that can't be access from outside the class.
Expected Results:
It is possible to do so.
Actual Results:
It isn't.
Version:
OS X Mavericks 10.9.3 (13D65), Xcode 6 beta seed 1 (6A215l), Swift version 1.0 (swift-600.0.34.4.5)
Notes:
Configuration:
N/A
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!
I really don't see how this is different to the idea of interfaces, other than being more complicated to find out what the permissions of a class are i.e. the example for anotherclass, to know what this has access to in MyClass I need to find out what the permissions of bazclass are, which reduces the ability to quickly find out what the access of what this class is (imagine its permissions don't come from bazClass now but fooClazz, which may have access to myclass etc...