What is the difference between a property and a variable in Swift?
Local variables are just things that you work with. You have full control over these, and if you change a variable in a function, nothing outside of your function is ever gonna know. If I write a framework and you use it, and I decide to change something about a function's local variables, your app that uses my framework will keep working just as if nothing changed.
Classes, on the other hand, describe a contract. When you use a class, you have access to everything they publicly advertise. This means that if I write a framework and you use it, if I ever change or remove a public member on a class, your code will break if you were previously using that member.
For this reason, in many languages, it's bad practice to mark instance variables as public. Instance variables having no logic attached, if I want at some point to trigger something when a field is changed or if I want to remove the field entirely (and instead report a value in a sub-object or something), then I'm stuck with changing the public contract (turning the field in a pair of get
/set
methods, for instance), and possibly breaking your code.
Swift makes properties an indirection for this reason. Swift properties can be treated as dumb values for the most part, but if you ever need to change from a stored value to a computed value or something, you can do it without changing your class's interface. That way, you don't break existing code that relies on the property.
Difference between variables
The second variable var b
is declared as a stored property:
In its simplest form, a stored property is a constant or variable that
is stored as part of an instance of a particular class or structure.
Stored properties can be either variable stored properties (introduced
by the var keyword) or constant stored properties (introduced by the
let keyword).
You could consider it as the default way for declaring properties.
The first variable var a
is declared as a computed property:
In addition to stored properties, classes, structures, and
enumerations can define computed properties, which do not actually
store a value. Instead, they provide a getter and an optional setter
to retrieve and set other properties and values indirectly.
You should declare a computed property when you need to edit the value of a stored property or even getting a new type based on another stored property.
Example:
struct MyStruct {
// stored properties
var var1: Int
var var2: Int
// comupted properties
var multiplication: Int {
return var1 * var2
}
var result: String {
return "result is: \(multiplication)"
}
}
Keep in mind that computed properties do not store the value, instead it just acts like a regular function that returns a value of a type.
Also, you could treat the computed property as a getter-setter for your -private- stored properties, example:
struct AccessControlStruct {
private var stored: String
var computed: String {
get {
return stored
}
set {
stored = newValue.trimmingCharacters(in: .whitespaces)
}
}
}
Since stored
declared as private, the only way is to access from out of the structure scope is by setting/getting its value by talking to computed
. Obviously, you could any desired edit to the value before setting/getting it to/from stored
, as an example, I am letting the newValue string of the computed
to be trimmed before setting it to stored
, it is also possible to edit the value before getting it.
Reference:
For more information, I would suggest to review:
The Swift Programming Language - Properties.
difference between a computed property and setting a function to a variable in Swift
The code in the computed property gets executed every time you reference that variable. The code in the property initialized by a closure is only executed once, during initialization.
Difference between properties and variables in iOS header file?
Defining the variables in the brackets simply declares them instance variables.
Declaring (and synthesizing) a property generates getters and setters for the instance variable, according to the criteria within the parenthesis. This is particularly important in Objective-C because it is often by way of getters and setters that memory is managed (e.g., when a value is assigned to an ivar, it is by way of the setter that the object assigned is retained and ultimately released). Beyond a memory management strategy, the practice also promotes encapsulation and reduces the amount of trivial code that would otherwise be required.
It is very common to declare an ivar in brackets and then an associated property (as in your example), but that isn't strictly necessary. Defining the property and synthesizing is all that's required, because synthesizing the property implicitly also creates an ivar.
The approach currently suggested by Apple (in templates) is:
Define property in header file, e.g.:
@property (assign, readonly) gameCenter;
Then synthesize & declare ivar in implementation:
@synthesize gameCenter = __gameCenter;
The last line synthesizes the gameCenter
property and asserts that whatever value is assigned to the property will be stored in the __gameCenter
ivar. Again, this isn't necessary, but by defining the ivar next to the synthesizer, you are reducing the locations where you have to type the name of the ivar while still explicitly naming it.
Is there a difference between an instance variable and a property in Objective-c?
A property is a more abstract concept. An instance variable is literally just a storage slot, like a slot in a struct. Normally other objects are never supposed to access them directly. A property, on the other hand, is an attribute of your object that can be accessed (it sounds vague and it's supposed to). Usually a property will return or set an instance variable, but it could use data from several or none at all. For example:
@interface Person : NSObject {
NSString *name;
}
@property(copy) NSString *name;
@property(copy) NSString *firstName;
@property(copy) NSString *lastName;
@end
@implementation Person
@synthesize name;
- (NSString *)firstName {
[[name componentsSeparatedByString:@" "] objectAtIndex:0];
}
- (NSString *)lastName {
[[name componentsSeparatedByString:@" "] lastObject];
}
- (NSString *)setFirstName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:@" "];
NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]];
self.name = [newNameArray componentsJoinedByString:@" "];
}
- (NSString *)setLastName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:@" "];
NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]];
self.name = [newNameArray componentsJoinedByString:@" "];
}
@end
(Note: The above code is buggy in that it assumes the name already exists and has at least two components (e.g. "Bill Gates" rather than just "Gates"). I felt that fixing those assumptions would make the actual point of the code less clear, so I'm just pointing it out here so nobody innocently repeats those mistakes.)
difference between two types of variable declarations?
TLDR: One is a function, one is a String
var name: String = "Name"
is a "regular" variable assignment. You create a var
of type String with the identifier name
and assign it the value "Name".
var name: String = {return "Name"}
won't compile. You're creating a var
of type String but then instead of assigning it a string you're assigning it a function. The curly braces indicate a function.
So...
var name = "Name"
print(name)
- Creates a variable
name
with the value name. - Prints the value of variable name [expected output
Name
]
Whereas
var name = {return "Name"}
print(name)
- Creates a variable
name
with the value of{return "Name"}
- Prints that to the console [expected output
(Function)
]
However
var name = {return "Name"}
print(name())
- Creates a variable
name
with the value of{return "Name"}
- Evaluates that function and prints the result [expected output
Name
]
Therefore
var sum = {return 1+2}
print(sum())
- Creates a variable
sum
with the value of{return 1+2}
- Evaluates that function and prints the result [expected output 3]
One last note-- you used single quotes ('
) but you should declare strings with double quotes ("
).
Related Topics
How to Implement Uipageviewcontroller That Utilizes Multiple Viewcontrollers
How to Set Adaptive Multiline Uilabel Text
Swift Playgrounds with Uiimage
Difference Between Dispatch_Async and Dispatch_Sync on Serial Queue
Ios6 Udid - What Advantages Does Identifierforvendor Have Over Identifierforadvertising
In iOS 12, When Does the Uicollectionview Layout Cells, Use Autolayout in Nib
Uicollectionview's Cell Disappearing
Swift Default Alertviewcontroller Breaking Constraints
How to Display Activity Indicator in Center of Uialertcontroller
App Killed by Sigkill When Changing Privacy Settings
iPhone Gps in Background Never Resumes After Pause
Nsurlconnection Get Request Returns -1005, "The Network Connection Was Lost"
How the Default Keyboard Comes Up When User Taps in Uiwebview
Swiftui - How to Avoid Navigation Hardcoded into the View
iOS 11 Customise Search Bar in Navigation Bar