Inheriting ugly: Swift subclass alters superclass' view of own stored properties? - swift

I have a subclass whose inheritance chain breaks down to look like this:
InputAccessoryEnabledTextField : UITextField : UIControl : UIView : UIResponder
InputAccessoryEnabledTextField provides an override:
private var myInputAccessoryController: UIInputViewController?
override var inputAccessoryViewController: UIInputViewController? {
get { myInputAccessoryController }
set { myInputAccessoryController = newValue }
}
The code above, working as the solution I was seeking, is from the accepted answer (#Sweeper) to a question I just asked on S.O. It is overriding an instance property of UIResponder.
However, it doesn't make sense to me. How can/does it work?
How is it possible that UITextField, superclass to my subclass, honors an override provided my subclass (InputAccessoryEnabledTextField)?
Doesn't that violate the inheritance hierarchy? Shouldn't only subclasses of InputAccessoryEnabledTextField be able to see its override, not superclasses?
Or do overrides apply to the whole object, such that every inherited superclass sees the state of some arbitrary outermost subclass? Or, is it that the iOS text subsystem is doing some really convoluted stuff?
Maybe this is too abstract a question for S.O. and I don't mind closing or deleting it, Just posting this to avoid a 'dialog' in the comments that the bot complains about.
Note: I don't find much clarity about it in Inheritence chapter of Swift 5 documentation *

In short
This is indeed the overriding of properties. Swift deals with properties by generating code that is equivalent to accessing properties via a via getters and setters. This allows to override a property by overriding the getter and the setter.
More explanations
Your snippet is overriding of a property
In your code, InputAccessoryEnabledTextField indirectly inherits from UIResponder, which has an existing property inputAccessoryViewController.
Your code snippet defines a new private property myInputAccessoryController, and uses it in the overriding of the inherited property inputAccessoryViewController, and more precisely, the overriding of its getter and setter.
Purpose in the case of your snippet
In fact, the purpose of this overriding is even explained in the documentation of inputAccessoryViewController:
The value of this read-only property is nil.
But what's the use of a property that is real only and returns only nil?
If you want to attach custom controls to a system-supplied input view controller (such as the system keyboard) or to a custom input view (...), redeclare this property as read-write in a UIResponder subclass.
How can property overriding even work?
While property overriding may seem weird at the first sight, we realize that this is just the normal overriding mechanism once we have understood that:
The stored or computed nature of an inherited property isn’t known by a subclass—it only knows that the inherited property has a certain name and type. You must always state both the name and the type of the property you are overriding, to enable the compiler to check that your override matches a superclass property with the same name and type.
Here we see the power of Swift's properties. You can make any property public, and still benefit from encapsulation and specialization, overriding it like functions. The explanation is that a property has two faces:
the class-internal implementation details: is the property stored or computed ?
the implicit class interface for the external world, including for subclasses: the outside world use the getter and the setter. These can be overridden.
the same principle works for property observers such as didSet: you can override them even if the base class didn't define any special behavior for them.
Here a small unrelated but extreme toy example to illustrate this feature (I would not recommend its design ;-) ):
class Lense {
init (opticalZoom: Int) {
magnifyingFactor = opticalZoom
}
// stored property
// And has implicitly a getter and a setter
var magnifyingFactor : Int = 2
}
class ElectronicLense : Lense {
// overriden property
// it overrides getter and setter, and uses the propery of the super-class to store the value
override var magnifyingFactor: Int {
get { super.magnifyingFactor * 5 }
set { super.magnifyingFactor = newValue / 5 }
}
// pass through property
var opticalFactor : Int {
get {super.magnifyingFactor}
}
}
var le = ElectronicLense(opticalZoom: 3)
print ("Zoom: \(le.magnifyingFactor) with an optical factor \(le.opticalFactor)")

The following example code demonstrates that a Swift superclass experiences its own properties through outermost subclass overrides!
(The example below proves #RobNapier correct, which I initially confirmed by successfully overriding UIResponder.inputAccessoryViewController and observing my viewController activated when the keyboard pops up for my subclassed UITextView : UIResponder)
The Good:
Swift overrides as explained by #RobNaipier in comments, make sense, at least from certain points of view. And can obviously be exploited for its interesting flexibility
The Bad:
However, it isn't what I assumed, and I was somewhat stunned that inheritance works that way, because intuitively I realized that letting subclasses tamper with superclasses` view of themselves is potentially risky, especially if one doesn't know superclass implementation details (as is the case with UIKits proprietary implementation code Apple doesn't release the source to the public).
The Ugly:
So while Swift inheritance lets the inheritors achieve tweak things for interesting or useful effect, and could be very handy in some cases, in practical use, for example with UIKit, it does leads to anticipated problems and confusion.
The coup de grâce, which I'm grateful that Rob pointed out, is that, due to the anticipated downsides, class inheritance with UIKit is increasingly discouraged by Apple and struct+protocol has been adopted by SwiftUI.
class TheSuperclass {
var x = 5
init() {
print("How superclass sees it before subclass initialized: x = \(x)")
}
func howSuperclassSeesItselfAfterSubclassInit() {
print("How superclass sees it after subclass initialized: x = \(x)")
}
}
class TheSubclass : TheSuperclass {
override var x : Int {
get { super.x + 10 }
set { super.x = newValue }
}
override init() {
super.init()
print("How subclass sees it after superclass" +
"initialized: x = \(x), super.x = \(super.x)")
}
}
TheSubclass().howSuperclassSeesItselfAfterSubclassInit()
The above code when run in Playground displays the following:
How superclass sees it before subclass initialized: x = 5
How subclass sees it after superclass initialized: x = 15, super.x = 5
How superclass sees it after subclass initialized: x = 15

Related

Hiding property setters by class in Swift

I would like to hide some property setters and initializers on my Swift model objects. These are reference data that the server provides, and under no circumstances should they be created or modified by the application. This is simple enough in Swift.
However, there is application in my project (a separate target) that needs to break this rule. It is a tool I use to populate the data in bulk, so of course needs to be able to initialize new model objects and set their properties.
What are my options for accomplishing this? I would rather not use a completely new project since it will mean a lot of code duplication. Is there some language-level way to keep this mutability hidden from one application but available to another?
If you declare a property with the let keyword. It can then only be set in the init of the type.
You can also declare a private setter to make the property readonly from the caller of the type but read/write inside the type
struct Foo {
private(set) var bar: Bool = true
func toggle() {
bar.toggle()
}
}
var foo = Foo()
let barState = foo.bar // This works
foo.toggle() // This works too
foo.bar.toggle() // This will make a compile time error

Singletons in Swift and Interface Builder

Background
I have a singleton class in my app, declared according following the one line singleton (with a private init()) in this blog post. Specifically, it looks like this:
#objc class Singleton {
static let Singleton sharedInstance = Singleton()
#objc dynamic var aProperty = false
private init() {
}
}
I would like to bind the state of aProperty to whether a menu item is hidden.
How I tried to solve the problem
Here are the steps I followed to do this:
Go to the Object Library in Interface Builder and add a generic "Object" to my Application scene. In the Identity inspector, configure "Class" to Singleton.
Create a referencing outlet in my App Delegate by Ctrl-dragging from the singleton object in Interface Builder to my App Delegate code. It ends up looking like this:
#IBOutlet weak var singleton: Singleton!
Go to the Bindings inspector for the menu item, choose "Hidden" under "Availability", check "Bind to", select "Singleton" in the combo box in front of it, and type aProperty under "Model Key Path".
The issue
Unfortunately, this doesn't work: changing the property has no effect on the menu item in question.
Investigating the cause
The issue appears to be that, despite declaring init() as private, Interface Builder is managing to create another instance of my singleton. To prove this, I added NSLog("singleton init") to the private init() method as well as the following code to applicationDidFinishLaunching() in my app delegate:
NSLog("sharedInstance = \(Singleton.sharedInstance) singleton = \(singleton)")
When I run the app, this is output in the logs:
singleton init
singleton init
sharedInstance = <MyModule.Singleton: 0x600000c616b0> singleton = Optional(<MyModule.Singleton: 0x600000c07330>)
Therefore, there are indeed two different instances. I also added this code somewhere else in my app delegate:
NSLog("aProperty: [\(singleton!.aProperty),\(String(describing:singleton!.value(forKey: "aProperty"))),\(Singleton.sharedInstance.singleton),\(String(describing:Singleton.sharedInstance.value(forKey: "aProperty")))] hidden: \(myMenuItem.isHidden)")
At one point, this produces the following output:
aProperty: [false,Optional(0),true,Optional(1)] hidden: false
Obviously, being a singleton, all values should match, yet singleton produces one output and Singleton.sharedInstance produces a different one. As can be seen, the calls to value(forKey:) match their respective objects, so KVC shouldn't be an issue.
The question
How do I declare a singleton class in Swift and wire it up with Interface Builder to avoid it being instantiated twice?
If that's not possible, how else would I go about solving the problem of binding a global property to a control in Interface Builder?
Is an MCVE necessary?
I hope the description was detailed enough, but if anyone feels an MCVE is necessary, leave a comment and I'll create one and upload to GitHub.
I just want to start my answer by stating that singletons should not be used for sharing global state. While they might seem easier to use in the beginning, they tend to generate lots of headaches later on, since they can be changed virtually from any place, making your program unpredictable some times.
That being said, it's not impossible to achieve what you need, but with a little bit of ceremony:
#objc class Singleton: NSObject {
// using this class behind the scenes, this is the actual singleton
class SingletonStorage: NSObject {
#objc dynamic var aProperty = false
}
private static var storage = SingletonStorage()
// making sure all instances use the same storage, regardless how
// they were created
#objc dynamic var storage = Singleton.storage
// we need to tell to KVO which changes in related properties affect
// the ones we're interested into
override class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String> {
switch key {
case "aProperty":
return ["storage.aProperty"]
default: return super.keyPathsForValuesAffectingValue(forKey: key)
}
}
// and simply convert it to a computed property
#objc dynamic var aProperty: Bool {
get { return Singleton.storage.aProperty }
set { Singleton.storage.aProperty = newValue }
}
}
Unfortunately you can’t return a different instance from init in Swift.
Here are some possible workarounds:
Make an outlet for an instance of your class in Interface Builder and then only reference that instance throughout your code. (Not a singleton per se, but you could add some runtime checks to make sure it’s only instantiated from a nib file and not from code).
Create a helper class for use in Interface Builder and expose your singleton as its property. I.e. any instance of that helper class will always return a single instance of your singleton.
Make an Objective-C subclass of your Swift singleton class and make its init's always return a shared Swift singleton instance.
There is a way around the problem in my particular case.
Recall from the question that I only wanted to hide and unhide a menu according to the state of aProperty in this singleton. While I was attempting to avoid write as much code as possible, by doing everything in Interface Builder, it seems in this case it's much less hassle to just write the binding programmatically:
menuItem.bind(NSBindingName.hidden, to: Singleton.sharedInstance, withKeyPath: "aProperty", options: nil)

How can I give clients read-access to an array in Swift? [duplicate]

In Swift, what is the conventional way to define the common pattern where a property is to be externally readonly, but modifiable internally by the class (and subclasses) that own it.
In Objective-C, there are the following options:
Declare the property as readonly in the interface and use a class extension to access the property internally. This is message-based access, hence it works nicely with KVO, atomicity, etc.
Declare the property as readonly in the interface, but access the backing ivar internally. As the default access for an ivar is protected, this works nicely in a class hierarchy, where subclasses will also be able to modify the value, but the field is otherwise readonly.
In Java the convention is:
Declare a protected field, and implement a public, read-only getter (method).
What is the idiom for Swift?
Given a class property, you can specify a different access level by prefixing the property declaration with the access modifier followed by get or set between parenthesis. For example, a class property with a public getter and a private setter will be declared as:
private(set) public var readonlyProperty: Int
Suggested reading: Getters and Setters
Martin's considerations about accessibility level are still valid - i.e. there's no protected modifier, internal restricts access to the module only, private to the current file only, and public with no restrictions.
Swift 3 notes
2 new access modifiers, fileprivate and open have been added to the language, while private and public have been slightly modified:
open applies to class and class members only: it's used to allow a class to be subclassed or a member to be overridden outside of the module where they are defined. public instead makes the class or the member publicly accessible, but not inheritable or overridable
private now makes a member visible and accessible from the enclosing declaration only, whereas fileprivate to the entire file where it is contained
More details here.
As per #Antonio, we can use a single property to access as the readOnly property value publicly and readWrite privately. Below is my illustration:
class MyClass {
private(set) public var publicReadOnly: Int = 10
//as below, we can modify the value within same class which is private access
func increment() {
publicReadOnly += 1
}
func decrement() {
publicReadOnly -= 1
}
}
let object = MyClass()
print("Initial valule: \(object.publicReadOnly)")
//For below line we get the compile error saying : "Left side of mutating operator isn't mutable: 'publicReadOnly' setter is inaccessible"
//object.publicReadOnly += 1
object.increment()
print("After increment method call: \(object.publicReadOnly)")
object.decrement()
print("After decrement method call: \(object.publicReadOnly)")
And here is the output:
Initial valule: 10
After increment method call: 11
After decrement method call: 10

OOP Terminology: class, attribute, property, field, data member

I am starting studying OOP and I want to learn what constitutes a class. I am a little confused at how loosely some core elements are being used and thus adding to my confusion.
I have looked at the C++ class, the java class and I want to know enough to write my own pseudo class to help me understand.
For instance in this article I read this (.. class attribute (or class property, field, or data member)
I have seen rather well cut out questions that show that there is a difference between class property and class field for instance What is the difference between a Field and a Property in C#?
Depending on what language I am studying, is the definition of
Property
Fields
Class variables
Attributes
different from language to language?
"Fields", "class variables", and "attributes" are more-or-less the same - a low-level storage slot attached to an object. Each language's documentation might use a different term consistently, but most actual programmers use them interchangeably. (However, this also means some of the terms can be ambiguous, like "class variable" - which can be interpreted as "a variable of an instance of a given class", or "a variable of the class object itself" in a language where class objects are something you can manipulate directly.)
"Properties" are, in most languages I use, something else entirely - they're a way to attach custom behaviour to reading / writing a field. (Or to replace it.)
So in Java, the canonical example would be:
class Circle {
// The radius field
private double radius;
public Circle(double radius) {
this.radius = radius;
}
// The radius property
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
// We're doing something else besides setting the field value in the
// property setter
System.out.println("Setting radius to " + radius);
this.radius = radius;
}
// The circumference property, which is read-only
public double getCircumference() {
// We're not even reading a field here.
return 2 * Math.PI * radius;
}
}
(Note that in Java, a property foo is a pair of accessor methods called getFoo() and setFoo() - or just the getter if the property is read-only.)
Another way of looking at this is that "properties" are an abstraction - a promise by an object to allow callers to get or set a piece of data. While "fields" etc. are one possible implementation of this abstraction. The values for getRadius() or getCircumference() in the above example could be stored directly, or they could be calculated, it doesn't matter to the caller; the setters might or might not have side effects; it doesn't matter to the caller.
I agree with you, there's a lot of unnecessary confusion due to the loose definitions and inconsistent use of many OO terms. The terms you're asking about are used somewhat interchangeably, but one could say some are more general than others (descending order): Property -> Attributes -> Class Variables -> Fields.
The following passages, extracted from "Object-Oriented Analysis and Design" by Grady Booch help clarify the subject. Firstly, it's important to understand the concept of state:
The state of an object encompasses all of the (usually static) properties of the object plus the current (usually dynamic) values of each of these properties. By properties, we mean the totality of the object's attributes and relationships with other objects.
OOP is quite generic regarding certain nomenclature, as it varies wildly from language to language:
The terms field (Object Pascal), instance variable (Smalltalk), member object (C++), and slot (CLOS) are interchangeable, meaning a repository for part of the state of an object. Collectively, they constitute the object's structure.
But the notation introduced by the author is precise:
An attribute denotes a part of an aggregate object, and so is used during analysis as well as design to express a singular property of the class. Using the language-independent syntax, an attribute may have a name, a class, or both, and optionally a default expression: A:C=E.
Class variable: Part of the state of a class. Collectively, the class variables of a class constitute its structure. A class variable is shared by all instances of the same class. In C++, a class variable is declared as a static member.
In summary:
Property is a broad concept used to denote a particular characteristic of a class, encompassing both its attributes and its relationships to other classes.
Attribute denotes a part of an aggregate object, and so is used during analysis as well as design to express a singular property of the class.
Class variable is an attribute defined in a class of which a single copy exists, regardless of how many instances of the class exist. So all instances of that class share its value as well as its declaration.
Field is a language-specific term for instance variable, that is, an attribute whose value is specific to each object.
I've been doing oop for more than 20 years, and I find that people often use different words for the same things. My understanding is that fields, class variables and attributes all mean the same thing. However, property is best described by the stackoverflow link that you included in your question.
Generally fields, methods, static methods, properties, attributes and class (or static variables) do not change on a language basis... Although the syntax will probably change on a per language basis, they will be function in the way you would expect across languages (expect terms like fields/data members to be used interchangably across languages)
In C#....
A field is a variable that exists for a given instance of a class.
eg.
public class BaseClass
{
// This is a field that might be different in each instance of a class
private int _field;
// This is a property that accesses a field
protected int GetField
{
get
{
return _field;
}
}
}
Fields have a "visibility" this determines what other classes can see the field, so in the above example a private field can only be used by the class that contains it, but the property accessor provides readonly access to the field by subclasses.
A property lets you get (sometimes called an accessor) or set (sometimes called a mutator) the value of field... Properties let you do a couple of things, prevent writing a field for example from outside the class, change the visibility of the field (eg private/protected/public). A mutator allows you to provide some custom logic before setting the value of a field
So properties are more like methods to get/set the value of a field but provide more functionality
eg.
public class BaseClass
{
// This is a field that might be different in each instance of a class
private int _field;
// This is a property that accesses a field, but since it's visibility
// is protected only subclasses will know about this property
// (and through it the field) - The field and property in this case
// will be hidden from other classes.
protected int GetField
{
// This is an accessor
get
{
return _field;
}
// This is a mutator
set
{
// This can perform some more logic
if (_field != value)
{
Console.WriteLine("The value of _field changed");
_field = value;
OnChanged; // Call some imaginary OnChange method
} else {
Console.WriteLine("The value of _field was not changed");
}
}
}
}
A class or static variable is a variable which is the same for all instances of a class..
So, for example, if you wanted a description for a class that description would be the same for all instance of the class and could be accessed by using the class
eg.
public class BaseClass
{
// A static (or class variable) can be accessed from anywhere by writing
// BaseClass.DESCRIPTION
public static string DESCRIPTION = "BaseClass";
}
public class TestClass
{
public void Test()
{
string BaseClassDescription = BaseClass.DESCRIPTION;
}
}
I'd be careful when using terminology relating to an attribute. In C# it is a class that can be applied to other classes or methods by "decorating" the class or method, in other context's it may simply refer to a field that a class contains.
// The functionality of this attribute will be documented somewhere
[Test]
public class TestClass
{
[TestMethod]
public void TestMethod()
{
}
}
Some languages do not have "Attributes" like C# does (see above)
Hopefully that all makes sense... Don't want to overload you!
Firstly, you need to select a language. For example, I would recommend you to select Ruby language and community. Until you select a language, you cannot escape confusion, as different communities use different terms for the same things.
For example, what is known as Module in Ruby, Java knows as abstract class. What is known as attributes in some languages, is known as instance variables in Ruby. I recommend Ruby especially for its logical and well-designed OOP system.
Write the following in a *.rb file, or on the command line in irb (interactive Ruby interpreter):
class Dog # <-- Here you define a class representing all dogs.
def breathe # <-- Here you teach your class a method: #breathe
puts "I'm breathing."
end
def speak # <-- Here you teach your class another method: #speak
puts "Bow wow!"
end
end
Now that you have a class, you can create an instance of it:
Seamus = Dog.new
You have just created an instance, a particular dog of class Dog, and stored it in the constant Seamus. Now you can play with it:
Seamus.breathe # <-- Invoking #breathe instance method of Seamus
#=> I'm breathing.
Seamus.speak # <-- Invoking #speak instance method of Seamus
#=> Bow wow!
As for your remaining terminology questions, "property" or "attribute" is understood as "variable" in Ruby, almost always an instance variable. And as for the term "data member", just forget about it. The term "field" is not really used in Ruby, and "class variable" in Ruby means something very rarely used, which you definitely don't need to know at this moment.
So, to keep the world nice and show you that OOP is really simple and painless in Ruby, let us create an attribute, or, in Ruby terminology, an instance variable of Dog class. As we know, every dog has some weight, and different dogs may have different weights. So, upon creation of a new dog, we will require the user to tell us dog's weight:
class Dog
def initialize( weight ) # <-- Defining initialization method with one argument 'weight'
#weight = weight # <-- Setting the dog's attribute (instance variable)
end
attr_reader :weight # <-- Making the dog's weight attribute visible to the world.
end
Drooly = Dog.new( 16 ) # <-- Weight now must provide weight upon initialization.
Drooly.weight # <-- Now we can ask Drooly about his weight.
#=> 16
Remember, with Ruby (or Python), things are simple.
I discovered in my question that Properties as defined in .Net are just a convenience syntax for code, and they are not tied to underlying variables at all (except for Auto-Implemented Properties, of course). So, saying "what is the difference between class property and class field" is like saying: what is the difference between a method and an attribute. No difference, one is code and the other is data. And, they need not have anything to do with each other.
It is really too bad that the same words, like "attribute" and "property", are re-used in different languages and ideologies to have starkly different meanings. Maybe someone needs to define an object-oriented language to talk about concepts in OOP? UML?
In The Class
public class ClassSample
{
private int ClassAttribute;
public int Property
{
get { return ClassAttribute; }
set { ClassAttribute = value; }
}
}
In the Program
class Program
{
static void Main(string[] args)
{
var objectSample = new ClassSample();
//Get Object Property
var GetProperty = objectSample.Property;
}
}

objective-c static/class method definition - what is the difference between "static" and "+"?

I'm wondering if someone can explain the difference between the functions below. They are both static, but require different signature syntaxes. I'm wondering how these are handled at runtime, and why you would use one over the other?
+ (int) returnInt:(NSString *)myString1 withString2:(NSString *)myString2
{
if ([myString1 isEqualToString:myString2])
return 1;
else
return 0;
}
vs.
static int returnInt(NSString *myString1, NSString *myString2)
{
if ([myString1 isEqualToString:myString2])
return 1;
else
return 0;
}
Thanks!
Unlike in (say) C++, where static member functions are just ordinary functions in the class' namespace, Objective-C has proper class methods.
Since classes are objects, calling a class method is really like calling an instance method on the class. The main consequences of this are:
1) Calling a class method incurs a slight (although generally inconsequential) overhead, since method calls are resolved at runtime.
2) Class methods have an implicit 'self' argument, just like instance methods. In their case, 'self' is a pointer to the class object.
3) Class methods are inherited by subclasses.
together, 2 and 3 mean that you can do stuff like this with a class method:
+ (id) instance
{
return [[[self alloc] init] autorelease];
}
then create a new class that inherits the method and returns a new instance of itself, rather than the superclass.
I believe that marking an ordinary c function static will just make it unavailable to files other than the one it's defined in. You'd generally do this if you wanted to make a helper function that is only relevant to one class and you wanted to avoid polluting the global namespace.