What is the preferred way of getting value in swift, var vs. func? - ios

What's the preferred way of getting a value in swift?
Using a read-only variable
var getString: String? {
return "Value"
}
or using a function?
func getString() -> String? {
return "Value"
}
Also, is there a performance difference between the two?

First, neither of these would be appropriate names. They should not begin with get. (There are historical Cocoa meanings for a get prefix that you don't mean, and so even if you mean "go out to the internet and retrieve this information" you'd want to use something like fetch, but certainly not in the case you've given.)
These issues are addressed in various sections of the Swift API Design Guidelines. First, a property is a property, whether it is stored or computed. So there is no difference in design between:
let someProperty: String?
and
var someProperty: String? { return "string" }
You should not change the naming just because it's computed. We can then see in the guidelines:
The names of other types, properties, variables, and constants should read as nouns.
Furthermore, as discussed in The Swift Programming Language:
Properties associate values with a particular class, structure, or enumeration. Stored properties store constant and variable values as part of an instance, whereas computed properties calculate (rather than store) a value.
So if this is best thought of as a value associated with the type (one of its "attributes"), then it should be a property (computed or stored). If it is something that is not really "associated" with the type (something that the caller expects this type to retrieve from elsewhere for instance), then it should be a method. Again from the Design Guidelines:
Document the complexity of any computed property that is not O(1). People often assume that property access involves no significant computation, because they have stored properties as a mental model. Be sure to alert them when that assumption may be violated.
If "stored properties as a mental model" doesn't match what you mean to express, then it probably shouldn't be a property in the first place (and you need to document the discrepancies if you make it a property anyway). So, for instance, accessing a property should generally have no visible side effects. And if you read from a property immediately after writing to it, you should get back the value you wrote (again, as a general mental model without getting into the weeds of multi-threaded programming).
If you use a method, it can often result in a different appropriate name. See the "Strive for Fluent Usage" section of the Design Guidelines for more on that. There are several rules for selecting good method names. As a good example of when to use properties vs methods, consider the x.makeIterator(), i.successor() and x.sorted() examples and think about why these are methods and why they're named as they are. This is not to say there is exactly one answer in all cases, but the Design Guidelines will give you examples of what the Swift team intends.

With no discernible difference in performance, make the choice for readability:
When an attribute behaves like a variable, use a property. Your example falls into this category.
When reading an attribute changes object state, use a function. This includes
Attributes that behave like a factory, i.e. returns new objects when you access them
Attributes that produce new values, such as random number generators
Peripheral readers
Input iterators
Of course, if the attribute is computed based on one or more argument, you have no other choice but to use a function.

Just as a note: If you want to use both getters and setters in Swift you can do as follows:
var myString: String {
get {
return "My string"
}
set {
self.myPrivateString = newValue
}
}
This way you can access your value as if it was a regular variable, but you can do some "under-the-hood magic" in your getters and setters

Related

why Objective-C convert to swift wrong

why

-(void)addSimpleListener:(id<XXSimpleListener>)listener
convert to swift look like this:
func add(_ listener: XXSimpleListener?) {
}
but change the method to this

-(void)addSimpleListener:(id<XXSimpleListening>)listener

and it will convert to this
func addSimpleListener(_ listener: XXSimpleListening?){
}
Xcode (or whatever tool you are using to do the conversion) is merely following Swift API guidelines. Specifically:
Omit needless words. Every word in a name should convey salient information at the use site.
More words may be needed to clarify intent or disambiguate meaning, but those that are redundant with information the reader already possesses should be omitted. In particular, omit words that merely repeat type information.
In the first case, the words SimpleListener in addSimpleListener is repeating the type of the parameter, so they are removed from the method name. However, in the second case, SimpleListener and SimpleListening does not look the same to whatever tool you are using, so it thinks that SimpleListener should be kept.
In my (human) opinion though, I think the method should be named addListener, because:
Occasionally, repeating type information is necessary to avoid ambiguity, but in general it is better to use a word that describes a parameter’s role rather than its type.
Listener is the role of the parameter.

Create object from Map - Dart

I have a class with a large number of properties that map to some JSON data I've parsed into a Map object elsewhere. I'd like to be able to instantiate a class by passing in this map:
class Card {
String name, layout, mana_cost, cmc, type, rarity, text, flavor, artist,
number, power, toughness, loyalty, watermark, border,
timeshifted, hand, life, release_date, starter, original_text, original_type,
source, image_url, set, set_name, id;
int multiverse_id;
List<String> colors, names, supertypes, subtypes, types, printings, variations, legalities;
List<Map> foreign_names, rulings;
// This doesn't work
Card.fromMap(Map card) {
for (var key in card.keys) {
this[key] = card[key];
}
}
}
I'd prefer to not have to assign everything manually. Is there a way to do what I'm trying to do?
I don't think there is a good way to do it in the language itself.
Reflection would be one approach but it's good practice to avoid it in the browser because it can cause code bloat.
There is the reflectable package that limits the negative size impact of reflection and provides almost the same capabilities.
I'd use the code generation approach, where you use tools like build, source_gen to generate the code that assigns the values.
built_value is a package that uses that approach. This might even work directly for your use case.

IList<> returned type instead of List<>

I found this method in one of examples for dependency Injecting a Controller. What is the reason of using an interface type IList<> instead of List<>?
public IList<string> GetGenreNames()
{
var genres = from genre in storeDB.Genres
select genre.Name;
return genres.ToList();
}
The actual reason, you're going to go ask the original programmer of that method that.
We can come up with a plausible reason however.
Input parameters should be as open and general as possible. Don't take an array if you can use any collection type that can be enumerated over. (ie. prefer IEnumerable<int> over List<int> if all you're going to do is do a foreach)
Output parameters and return types should be as specific as possible, but try to return the most usable and flexible data type possible without sacrificing performance or security. Don't return a collection that can only be enumerated over (like IEnumerable<int>) if you can return an array or a list you created specifically for the results (like int[] or List<int>).
These guidelines are listed many places on the internet (in different words though) and are there to help people write good APIs.
The reason why IList<T> is better than List<T> is that you're returning a collection that can be:
Enumerated over (streaming access)
Accessed by index (random access)
Modified (Add, Delete, etc.)
If you were to return List<T> you wouldn't actually add any value, except to return a concrete type instead of just any type that happens to implement that interface. As such, it is better to return the interface and not the concrete type. You don't lose any useful features on the outside and you still retain the possibility of replacing the actual object returned with something different in the future.
targeting interface is always better than targeting concrete type.
So if returning IList, that means anything implementing IList could be returned, give better separation.
check this out for more info
Why is it considered bad to expose List<T>?
It's somewhat basic rule in OOP. It's good to have an interface so your clients (the caller of GetGenreNames ) knows only how to call (function signature, only thing to remember, rather than implementation details etc) to get serviced.
Programming to interface supports all goodies of OOP. its more generalized, maintains separation of concerns, more reusable.

Properties in Categories

Why is it allowed to declare properties in categories when neither they nor their accessor methods are synthesized? Is there any performance overhead involved?
Is categorisation purely a compiler technique?
I'm trying to understand how categories work. This just explains what to do and what not to do. Are there any sources which go into more detail?
EDIT : I know that I can use associated references. Thats not what I'm asking for. I want to know why are the properties not synthesised? Is there a performance issue or a security issue if the compiler synthesises them? If there is I want to know what and how?
Why is it allowed to declare properties in categories [...] ?
Properties have many aspects (during compile- and runtime).
They always declare one or two accessor methods on the class.
They can change the selector when the compiler transforms dot notation to messages.
In combination with the #synthesize directive (or by default) they can make the compiler synthesize accessor methods and optionally ivars.
They add introspection information to the class which is available during runtime.
Most of these aspects are still useful when declaring properties in categories (or protocols) and synthesizing is not available.
Is categorisation purely a compiler technique?
No. Categories, as properties, have both compile time as well as runtime aspects.
Categories, for example, can be loaded from dynamic libraries at a later time. So there might already be instances of a class that suddenly gets new methods added. That's one of the reasons categories cannot add ivars, because old objects would be missing these ivars and how should the runtime tell if an object has been created before or after the category has been added.
Before you go into categories, please reconsider the concept of properties in Obj-C: A property is something you can write and read to in an abstract sense, using accessors. Usually, there is an instance variable assigned to it, but there is no need to do so.
A property may also be useful e.g., to set a number of different instance variables in a consistent way, or to read from severals variables or do some calulation.
The crucial fact here: there is no need to have an instance variable assigned to a property.
A category serves as an extensiton of an object's behavior, i.e., to extend its set of methods, without changing the data. If you see a property in it abstract sense, then it add accessors, thus it matches the idea of a category.
But if you synthesize it, an instance variable would be generated what contradicts the idea of a category.
Thus, a property in a category makes only sense if you use it in the uncommon, abstract way, and #synthesize is to ease the common way.
You may want to read NSHipster about how to implement properties storage in categories.
Quoting from the article: "Why is this useful? It allows developers to add custom properties to existing classes in categories, which is an otherwise notable shortcoming for Objective-C."
#synthesize informs the compiler to go ahead and provide a default implementation for the setter and the getter.
Said default setters/getters rely on the existence of some kind of storage inside the object.
Categories do not offer any extra storage, so default setters/getters would have no place to store into, or read from.
An alternative is to use:
#dynamic
and then provide your own implementation and own storage for the said properties.
One way is to use associated objects.
Another would be to store into/read from some completely unrelated place, such as some accessible dictionary of NSUserDefaults or ...
In some cases, for read only properties, you can also reconstruct/compute their values at runtime without any need to store them.

Semantics of OMG IDL attributes

I'm working on the verification of an interface formalised in the OMG's IDL, and am having problems finding a definitive answer on the semantics of getting an attribute value. In an interface, I have an entry...
interface MyInterface {
readonly attribute SomeType someName;
};
I need to know if it is acceptable for someObj.someName != someObj.someName to be true (where someObj is an instance of an object implementing MyInterface).
All I can find in OMG documentation in regards to attributes is...
(5.14) An attribute definition is logically equivalent to declaring a
pair of accessor functions; one to retrieve the value of the attribute
and one to set the value of the attribute.
...
The optional readonly keyword indicates that there is only a single
accessor function—the retrieve value function.
Ergo, I'm forced to conclude that IDL attributes need not be backed by a data member, and are free to return basically any value the interface deems appropriate. Can anyone with more experience in IDL confirm that this is indeed the case?
As we know, IDL interface always will be represented by a remote object. An attribute is no more then a syntatic sugar for getAttributeName() and setAttributeName(). Personally, i don't like to use attribute because it is hardly to understand than a simply get/set method.
CORBA also has valuetypes, object by value structure - better explaned here. They are very usefull because, different from struct, allow us inherit from other valuetypes, abstract interface or abstract valuetype. Usualy, when i'm modeling objects with alot of
get/set methods i prefer to use valuetypes instead of interfaces.
Going back to your question, the best way to understand 'attribute' is looking for C#. IIOP.NET maps 'attribute' to properties. A property simulates a public member but they are a get/set method.
Answering your question, i can't know if someObj.someName != someObj.someName will return true or false without see the someObj implementation. I will add two examples to give an ideia about what we can see.
Example 1) This implementation will always return false for the expression above:
private static i;
public string getSomeName() {
return "myName" i;
}
Example 2) This implementation bellow can return true or false, depending of concurrency or 'race condition' between clients.
public string getSomeName() {
return this.someName;
}
public setSomeName(string name) {
this.someName = name;
}
First client can try to access someObj.someName() != someObj.someName(). A second client could call setSomeName() before de second call from the first client.
It is perfectly acceptable for someObj.someName != someObj.someName to be true, oddly as it may seem.
The reason (as others alluded to) is because attributes map to real RPC functions. In the case of readonly attributes they just map to a setter, and for non-readonly attributes there's a setter and a getter implicitly created for you when the IDL gets compiled. But the important thing to know is that an IDL attribute has a dynamic, server-dictated, RPC-driven value.
IDL specifies a contract for distributed interactions which can be made at runtime between independent, decoupled entities. Almost every interaction with an IDL-based type will lead to an RPC call and any return value will be dependent on what the server decides to return.
If the attribute is, say, currentTime then you'll perhaps get the server's current clock time with each retrieval of the value. In this case, someObj.currentTime != someObj.currentTime will very likely always be true (assuming the time granularity used is smaller than the combined roundtrip time for two RPC calls).
If the attribute is instead currentBankBalance then you can still have someObj.currentBankBalance != someObj.currentBankBalance be true, because there may be other clients running elsewhere who are constantly modifying the attribute via the setter function, so you're dealing with a race condition too.
All that being said, if you take a very formal look at the IDL spec, it contains no language that actually requires that the setting/accessing of an attribute should result in an RPC call to the server. It could be served by the client-side ORB. In fact, that's something which some ORB vendors took advantage of back in the CORBA heyday. I used to work on the Orbix ORB, and we had a feature called Smart Proxies - something which would allow an application developer to overload the ORB-provided default client proxies (which would always forward all attribute calls to the server hosting the target object) with custom functionality (say, to cache the attribute values and return a local copy without incurring network or server overhead).
In summary, you need to be very clear and precise about what you are trying to verify formally. Given the dynamic and non-deterministic nature of the values they can return (and the fact that client ORBs might behave differently from each other and still remain compliant to the CORBA spec) you can only reliably expect IDL attributes to map to getters and setters that can be used to retrieve or set a value. There is simply no predictability surrounding the actual values returned.
Generally, attribute does not need to be backed by any data member on the server, although some language mapping might impose such convention.
So in general case it could happen that someObj.someName != someObj.someName. For instance attribute might be last access time.

Resources