This question already has answers here:
Why convenience keyword is even needed in Swift?
(6 answers)
Closed 5 years ago.
The convenience keyword in swift completely confused me. It doesn't seem useful at all. Calling other initializer (or say constructor) in same or super class is a very common feature in object oriented languages, like Java, C# and etc. If any member is not initialized, the compiler gives a warning. It seems the only thing it does is to restrict the call to other initializer to same class, which makes it seems even more useless. So, why bother having this keyword at all?
I saw some other threads online discussing about this but none of them is really convincing.
Does anyone know the real purpose of this keyword?
From The Swift Programming Language:
You do not have to provide convenience initializers if your class does not require them. Create convenience initializers whenever a shortcut to a common initialization pattern will save time or make initialization of the class clearer in intent.
So, basically, they are for convenience.
Related
Headline: description called by super.init()
This is a new take on an old question. As a primarily Swift programmer I tend to not use NSObject for class definitions because of the residual side effects of Objective-C. Like if I have a read-only property called length and I then want to create a setter function called setLength, I get warnings about it conflicting with a similar definition from Objective-C. I just discovered the set(var){} setter. If I subclass a Cacoa class like UIDocument, etc. that inherit from NSObject, I have to live with these side effects.
I have a class that uses two other classes in the property definitions, none of them NSObjects. This class has a description computed variable that uses the description computed variables for the other two classes in its composition. All three classes need to conform to the CustomStringConvertable protocol. Ok, everything is good.
At some point this class got upgraded to being a UIDocument and the CustomStringConvertable became redundant and was removed. Everything still works.
Here is what I found out today. I wanted to break at a point in the program where it was printing one of the two properties and as a convenience I set the break point in the description variable for that class, thinking that it should only be called at the point I am interested in, where it is printed out. What I discovered is that the description variable gets called during all the super.init() of the UIDocument sub-class! And there were a few of them. I think composing strings as being relatively expensive but didn't care because they were only used in debug, but with them being called and who knows how they are used in super.init(), I need to change this.
I checked another UIDocument class in the same program that has 200 files associated with it and it is also calling description in super.init().
Does anyone have any input on the Best Practices for using description vs debugDescription?
I'm going to answer my own question as a matter of documentation.
I switched the UIDocuments subclasses to define and use debugDescription. I am debugging some code that loads all the files and does some manipulation and I was able to reduce the load time from 9.8 seconds to 6.8 seconds.
I also went through all the places where the Swift 3 conversion added String(describing:) to the program and found I could change a lot of them to using debugDescription and eliminate the String(describing:) wrapper.
I think the best practice is to only define and use debugDescription and for my non-NSObjects change conformance from CustomStringConvertable to CustomDebugStringConvertable.
This question already has answers here:
Difference between static function and singleton class in swift [closed]
(3 answers)
Closed 6 years ago.
I have made a class that will contain all the utility methods. So, instead of making it as a singleton, I have marked the methods as static and accessing those methods by the ClassName.methodName without the need for instantiation.
Is this approach OK?
Just consider that a singleton is used in order to ensure that only one instance exists for a given class, and that there’s a global access point to that instance.
I believe that having all utility functions marked as static within a class is a good approach since, as you have stated, you will need to use ClassName.methodName in order to use them.
In addition, based on what you want to achieve and the information provided by this link, I would reassert that having a class with static methods is the best alternative.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I was wondering why you cant use the static keyword in a class.
I know that you can use it in a struct but not in a class
Does anyone know why they choose for this?
And if so are there any advantages for letting static away?
It is a terminological bêtise. What Apple did was decide that you use static in an enum or struct and class in a class. In my view this was a very foolish decision, as they are exactly parallel to one another. Many people have posted on the dev forums suggesting that they just call them all static.
The outcome is a candidate for Occam's Razor: two phrases, e.g. static property and class property, or static method and class method, that mean exactly the same thing. And then they try to cover their tracks in the documentation by adding a third term as an umbrella, "type property" (meaning a static-or-class property) or "type method" (meaning a static-or-class method), which just makes the situation even worse.
The badness of the situation is also revealed by what you have to do in protocols: you declare a class property in a protocol and then if a struct adopts it, it calls that a static property. Same thing with a class method in a protocol; an adopting struct must call that a static method. You'd think that this alone would have told them they'd done a bad thing.
Edit: The more I think about it, the more I like the proposal put forth by newacct in a comment below. If Apple had simply used the umbrella keyword type here as part of the language, the whole problem would have been solved. We could have declarations type var, type let, type func, and this would work equally in enums, structs, classes, and protocols across the board.
From the Swift Language Guide on Methods, Apple has chosen to differentiate the syntax used, based upon the fundamental Type that you're building.
Classes declare "Type Methods" with the keyword Class. Example:
class MyClass {
class func myFunc(){ ... }
}
Structs declare "Type Methods" with the keyword Static. Example:
struct MyStruct {
static func myFunc(){ ... }
}
In both cases, crating a Type Method allows you to invoke the method without first creating an instance of the class or struct.
Whereas a non class/static function would require something like
let instance = MyClass()
instance.myFunc()
... declaring the variable as a Type Method allows something like
MyClass.myFunc()
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why does fast enumeration not skip the NSNumbers when I specify NSStrings?
I noticed some unexpected behavior while using fast enumeration recently. In hindsight I was probably expecting fast enumeration to do more than it's intended for, so I'm looking for some clarification on how it's actually works.
Say I have a parent class Shape with 2 child classes, 3SidedShape and 4SidedShape. I have an array called myShapes, that contains objects from both the 3 and 4 sided classes.
If I wanted to search through the array myShapes, but I'm only concerned with 3 sides shapes what I was doing is:
for (3SidedShape *shape in myShapes)
My thought was that I would only be iterating over objects of class 3SidedShape, but that is not the case? I guess I'm casting all objects as 3SidedShape whether they like it or not. I'm evening returning the object after as a completely different class. Granted I'm not calling any methods that both classes don't have, but I didn't expect class siblings to just re-cast so easily without a hitch? Did I just get lucky here or can you really enumerate as any class you please regardless of relation? Can anyone explain what actually happens during enumeration?
The type specified in a for...in loop, aka fast enumeration, casts all the elements in the collection to the specified type. The reason why they are "re-cast so easily" is that casting does NOT turn one type of object into another (how would that work?). It's a hint to the compiler telling it to treat the object as if it were the other type, as if to say "don't worry, this object is of (insert type), so type check it as such." Sending the object a message it can't handle, but the type it was casted to can, will still crash the app. What you should do is this:
for (id shape in myShapes){
if ([shape isKindOfClass: [3SidedShape class]]){
//insert code here
}
}
That code assumes nothing of type, using introspection to only perform the code for objects who are of type 3SidedShape or a subclass of 3SidedShape. For exact checking (excluding subclasses) use isMemberOfClass:. Be wary of using isMemberOfClass: to test membership of a class in a class cluster (NSNumber), however, due to their more complex internal implementation.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
dynamic properties in objective c
How can I add properties to an object at runtime?
Is there a way to actually create properties in runtime dynamically in iOS?
I am experimenting something here, and just wanted to see if it be possible?
Thanks.
Properties are mapped to methods so you can add properties dynamically the same way you add methods dynamically using -[NSObject forwardInvocation:] and -[NSObject methodSignatureForSelector:] though you will have to use method syntax to call these methods and it can get complicated if you want to use primitive type properties.
you can generate types dynamically using ivars and methods, but there is not a means to get all the functionality of a declared property via one or two runtime calls.
a handful of functions should be all that is needed to accomplish the common routines, but a complete implementation would require some work and some syntactical noise.