Access one specific object from class name? - static

I want to access a specific object with the class name. This object may change, so it is not a singleton.
Like:
MyClass.actualView
or
MyClass.actualView()
Since I get class var are not yet supported as an error, any good short ways in your mind?

I used a global variable and a calculated type property. Only the constant type property are not supported yet.
private var globalVar: MyClass? = nil
class MyClass {
internal class var sharedInstance : MyClass {
get {
return globalVar
set {
globalVar = newValue
}
}
}
Before using it, it must be set from any of the instances:
MyClass.sharedInstance = self
Now I could set and get the type property like I could in every other language, until Apple makes it easier and supports constant type properties.
I can get the sharedInstance from anywhere inside the project (even accessible from Objective-C, when you add #objc before the internal-keyword
Swift:
MyClass.sharedInstance
Objective-C:
[MyClass sharedInstance];

Related

Swift: Cannot add element in Array from another object

I am struggeling with swift syntax . I want to add objects to an array but I have syntax errors.
The array is located in class Document, and the class that should add objects is in class Viewcontroller.
The array is of type Content:
public class Content: NSObject {
#objc var bankAccSender: String?
#objc var bankAccReceiver: String?
Declaration snippest in Document:
class Document: NSDocument {
var content=[Content]()
override init() {
super.init()
self.content = [Content]()
// force one data record to insert into content
content += [Content (… )] // checked with debugger
The ViewController has assigned the represented Object
contentVC.representedObject = content
But adding data in ViewController gives a compiler error „Type of expression is ambiguous without more context“:
var posting = Content(…)
self.representedObject.append(posting)
Hope you can help..
You can't append an element to an object of type Any. What you need is to replace the existing value with a new collection:
representedObject = (representedObject as? [Content] ?? []) + CollectionOfOne(posting)
representedObject is of type Any?, which is a very difficult type to work with in Swift. Since you already have a content property, I would probably adjust that, and then re-assign it to representedObject.
You can also try this (untested), as long as you are certain that the type is always [Content]:
(self.representedObject as! [Content]).append(posting)
It's possible you'll need some more complex like this:
(self.representedObject as! [Content]?)!.append(posting)
As I said, Any? is an incredibly obnoxious type. You probably want to wrap this up into a function. Or I you can avoid using representedObject, then I would recommend that. In many cases you don't need it. It's often just a convenience (in ObjC; in Swift, it's very hard to use).

Generating complex types with all properties equivalent

Does AutoFixture have a facility to create multiple instances of a given type with all the same data? My classes are not serializable and I need two models which are not reference equivalent, but instead have matching properties.
public class Foo
{
// Many more properties and similar models needing the same semantics.
public string Name { get; set; }
}
var a = fixture.Create<Foo>();
var b = fixture.Create<Foo>();
Assert.False(ReferenceEquals(a, b));
Assert.Equal(a.Name, b.Name);
I don't think that AutoFixture can do this, but Albedo can. While this is only proof-of-concept code, it should illustrate the general idea, I hope.
Create a new class, deriving from ReflectionVisitor<T>:
public class PropertyCopyVisitor<T> : ReflectionVisitor<T>
{
private readonly T source;
private readonly T destination;
public PropertyCopyVisitor(T source, T destination)
{
this.source = source;
this.destination = destination;
}
public override IReflectionVisitor<T> Visit(
PropertyInfoElement propertyInfoElement)
{
var pi = propertyInfoElement.PropertyInfo;
pi.SetValue(this.destination, pi.GetValue(this.source));
return this;
}
public override T Value
{
get { return this.destination; }
}
}
The pivotal part of the implementation is the Visit overload where it uses Reflection to copy each property from source to destination object.
Since this implementation mutates destination, the Value property is never used, but it has to be there because it's abstract in ReflectionVisitor<T>...
You can now write your test as:
var fixture = new Fixture();
var a = fixture.Create<Foo>();
var b = fixture.Create<Foo>(); // Or just create a new, empty Foo...
// This copies all properties from a to b:
new TypeElement(typeof(Foo)).Accept(new PropertyCopyVisitor<Foo>(a, b));
Assert.False(ReferenceEquals(a, b));
Assert.Equal(a.Name, b.Name);
Here, I still used fixture to create b, but you don't have to do that, because all properties are going to be overwritten anyway. If Foo has a parameterless constructor, you could instead simply use new Foo(); it'd make no difference.
This proof-of-concept explicitly only copies properties. If you need to copy fields as well, you'll have to override the appropriate Visit method as well. Furthermore, if the objects in question take constructor arguments, you'll need to deal with those explicitly as well.
If you find it tedious to write new TypeElement(typeof(Foo)).Accept(new PropertyCopyVisitor<Foo>(a, b));, I'm sure you can figure out a way to write a helper method around it.
As an additional note, PropertyCopyVisitor doesn't have to be generic, because it doesn't actually use the T type argument for anything. I just like the type safety that this gives the constructor...

How do I get array item type in TypeScript using the Reflection API?

I have the following little class in TypeScript, with some public fields decorated:
class Company {
#dataMember
public name: string;
#dataMember
public people: Person[];
}
class Person {
// ...
}
By using reflect metadata, I can determine the types of Company properties name and people: they are the constructor functions String and Array, respectively, which is expected and logical.
My property decorator function:
function decorate(target: Object, propertyKey: string | symbol): void {
var reflectType = Reflect.getMetadata("design:type", target, propertyKey);
// ...
}
But how could I determine the type (constructor function) of array elements? Is it even possible? In the above example, it should be (a reference to) Person.
Note: I need the type reference before instantiation, and because of this, it is impossible to dynamically determine the type using array items: there are no array items, there isn't even an Array instance.
I don't think this is possible as of now. If you see the generated js file, for array of anything, it creates metadata with type as Array without any information on type.
__decorate([
dataMember_1.dataMember,
__metadata('design:type', Array)
], Company.prototype, "people", void 0);
For built-in types, one way I could think of solving this problem is to pass the type in the decorator itself and writing the custom logic in the decorator code.
#dataMember(String)
myProp: Array<String>
For Custom objects, most of the time when the decorator call is fired, the module is not fully loaded. So, one way is to pass the class name and parse it later.
#dataMember("People")
people: People[]

What does static refer to being "stuck" to?

I'm trying to give myself a mapped idea of the word static (using my current noun definition of static, not having a good understanding of the adjective definition), but it would seem that non-static variables and methods actually are "stuck" (or better said referencing/referring) to objects/instances. So what is the terminology static actually describing about the declared methods/variables?
The words "static" and "dynamic" are frequently used as opposites in programming terminology.
Something that is dynamic is something that changes; in the context of a class, it is something that takes on different values or behaviors with each instance (object).
Something that is static does not change; it is in stasis. So a static variable of a class does not take on different values with each instance.
Static electricity doesn't move; it is stuck in one place, on your socks. Dynamic electricity, in motion in a wire, can do much more powerful things.
I think this question here provides a very detailed answer: What is "static"?
The concept of static has to do with whether something is part of a class or an object (instance).
In the case of the main method which is declared as static, it says that the main method is an class method -- a method that is part of a class, not part of an object. This means that another class could call a class method of another class, by referring to the ClassName.method. For example, invoking the run method of MyClass would be accomplished by:
MyClass.main(new String[]{"parameter1", "parameter2"});
On the other hand, a method or field without the static modifier means that it is part of an object (or also called "instance") and not a part of a class. It is referred to by the name of the specific object to which the method or field belongs to, rather than the class name:
MyClass c1 = new MyClass();
c1.getInfo() // "getInfo" is an instance method of the object "c1"
As each instance could have different values, the values of a method or field with the same name in different objects don't necessarily have to be the same:
MyClass c1 = getAnotherInstance();
MyClass c2 = getAnotherInstance();
c1.value // The field "value" for "c1" contains 10.
c2.value // The field "value" for "c2" contains 12.
// Because "c1" and "c2" are different instances, and
// "value" is an instance field, they can contain different
// values.
Combining the two concepts of instance and class variables. Let's say we declare a new class which contains both instance and class variables and methods:
class AnotherClass {
private int instanceVariable;
private static int classVariable = 42;
public int getInstanceVariable() {
return instanceVariable;
}
public static int getClassVariable() {
return classVariable;
}
public AnotherClass(int i) {
instanceVariable = i;
}
}
The above class has an instance variable instanceVariable, and a class variable classVariable which is declared with a static modifier. Similarly, there is a instance and class method to retrieve the values.
The constructor for the instance takes a value to assign to the instance variable as the argument. The class variable is initialized to be 42 and never changed.
Let's actually use the above class and see what happens:
AnotherClass ac1 = new AnotherClass(10);
ac1.getInstanceVariable(); // Returns "10"
AnotherClass.getClassVariable(); // Returns "42"
Notice the different ways the class and instance methods are called. The way they refer to the class by the name AnotherClass, or the instance by the name ac1. Let's go further and see the behavioral differences of the methods:
AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);
ac1.getInstanceVariable(); // Returns "10"
AnotherClass.getClassVariable(); // Returns "42"
ac2.getInstanceVariable(); // Returns "20"
AnotherClass.getClassVariable(); // Returns "42"
As can be seen, an instance variable is one that is held by an object (or "instance"), therefore unique to that particular instance, which in this example is the objects referred to by ac1 and ac2.
A class variable on the other hand is only unique to that entire class. To get this point across even better, let's add a new method to the AnotherClass:
public int getClassVariableFromInstance() {
return classVariable;
}
Then, run the following:
AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);
ac1.getInstanceVariable(); // Returns "10"
ac1.getClassVariableFromInstance(); // Returns "42"
ac2.getInstanceVariable(); // Returns "20"
ac2.getClassVariableFromInstance(); // Returns "42"
Although getClassVariableFromInstance is an instance method, as can be seen by being invoked by referring to the instances ac1 and ac2, they both return the same value, 42. This is because in both instance methods, they refer to the class method classVariable which is unique to the class, not to the instance -- there is only a single copy of classVariable for the class AnotherClass.
I hope that some what clarifies what the static modifier is used for.
The Java Tutorials from Sun has a section called Understanding Instance and Class Members, which also goes into the two types of variables and methods.

Convert String into an object instance name

I'm trying to turn an string into an instance name.
stage.focus = ["box_"+[i+1]];
this gives me back = box_2;
but I need it to be an object not a string.
In as2 I could use eval. How do I do it in as3?
The correct syntax is:
this["box_"+(i+1)]
For example if you would like to call the function "start" in your main class, you'd do it this way:
this["start"]();
Same thing goes for variables. Since all classes are a subclass of Object you can retrieve their variables like you would with an ordinary object. A class like this:
package{
import flash.display.Sprite;
public class Main extends Sprite{
public var button:Sprite;
public function Main(){
trace(this["button"]);
}
}
}
Would output:
[object Sprite]
If you want to access a member of the current class, the answers already given will work. But if the instance you are looking isn't part of the class, you are out of luck.
For example:
private function foo():void {
var box_2:Sprite;
trace(this["box_"+(i+1)]);
}
Won't work, because box_2 isn't a part of the class. In that case, it is highly recommended to use an array.
If you want to access a DisplayObject (for example, a Sprite or a MovieClip) you also can use getChildByName. But in that case, box_2 will be the name of the object, instead of the name of the variable. You set the name like
var box:Sprite;
box.name = "box_2";
But again, I recommend an array.

Resources