I have a BOOL property and at the start this property equals NO. I want to set this property to YES from the start of my program, but with opportunity to toggle it.
For this, I made this getter:
-(BOOL)turn
{
if(!_turn)
_turn = YES;
return _turn;
}
This getter set my turn property to YES, but it makes it "constant", always YES.
Why?
I thought
if(!_turn)
construction is specially for the reason where you want set the "not set yet" object value
Can you answer me why this is so? And how can I set my property value to what i want. Thanks.
Look at your action table:
turn: False True
!turn turn = YES Do Nothing
When _turn is false, you flip it too true. When _turn is true, you do nothing (there's no else statement). Then you return the value of _turn. So yea, you are returning true in all cases.
To be honest, the design is not very good. If you want to set the initial value of the variable to a certain value, do that in the init method. Then provide another method that simply toggles the value:
-(BOOL) toggleTurn {
_turn = !_turn;
return _turn;
}
Usually the lazy initialization technique is used with pointers to objects, not with primitive types. This because a BOOL has only two possibile states: NO and YES, there isn't the "undefined state" which is usually associated with nil for objects.
The reason why it doesn't toggle is that you aren't toggling it, you are just setting it to YES when it's equal to NO, but you aren't handling the case when it's equal to YES. If you want to toggle it just do that:
-(BOOL)turn
{
return _turn= !_turn;
}
PS: Whoever could argue that your method isn't properly a getter, because you are altering the variable before returning it. So I suggest to just return _turn without toggling it, and to create another separated method to toggle the variable.
Also I would like to mention that what you are doing is not called lazy initialization, I'll show you a case of lazy initialization:
// In the interface:
#property(nonatomic,readonly) NSNumber* turnObject;
// In newer compiler versions it should be auto synthesized to _turnObject
// In the implementation:
-(BOOL) turn
{
// In this case I am not toggling it
if(!_turnObject) // Equal to if(turnObject==nil)
_turnObject= #(NO); // Equal to _turnObject=[NSNumber numberWithBOOL: NO];
return _turnObject;
}
Related
What is it called when you define a variable/property with a getter and setter, such that the language does not automatically generate a backing variable?
E.g. in Swift, we could define a modalViewController property that doesn't create a backing variable:
extension MyViewController {
var modalViewController: UIViewController? {
get { return self.presentedViewController }
set { self.present(newValue, animated: true) }
}
}
What's the proper term to describe the modalViewController property?
I know that if it's only gettable, it would be called a computed property:
extension Int {
var isEven: Bool {
get { return self % 2 == 0 }
}
}
However, I'm looking for a term for something that is both settable and gettable.
The reason I'm looking for a term is that I want to ask a question related to these types of properties, and would like to use common, non-ambiguous language. I thought this would be called a virtual property, but it doesn't appear to be the proper name as virtual has a different meaning in OOP.
Even though they have a setter too, Swift (at least) calls these "computed properties" (emphasis added):
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.
From what I understand, Swift was presented as an upgrade from Objective-C for developers to use in their applications. One new concept that went with it is the concept of "optional variables," or any sort of variable that may hold nothing.
In Objective-C, this was almost implicit. You could assign a value of nil to many kinds of variables, but, in Swift, the variable has to be an optional.
For instance, this sort of statement is completely okay in Objective-C:
SKNode *someNode = [SKNode new];
// some methods appear that may change the value of "someNode."
// they are right here. These "methods" might leave "someNode"
// equal to "nil". If not, they might set "someNode" to a node
// equal to a node that exists already.
// check if it's nil.
if (someNode == nil) {
// code to run if it exists
}
else {
// code to run if it doesn't exist
}
And in Swift, this code:
var node = SKNode.new()
// this "node" is created/used like "someNode" is used above.
if node != nil {
// code that will run if node exists
}
else {
// code to run if node doesn't exist
}
will give the error:
Binary operator '!=' cannot be applied to operands of type 'SKNode' and 'nil'
However, change the Swift initialization of node to this, and you'll be gold, because you're explicitly defining node as an optional.
var node : SKNode? = SKNode.new()
May I add, this doesn't work either:
var node = SKNode?.new()
Giving the error:
'SKNode?.Type' does not have a member named 'new'
Why does the node have to be explicitly defined as an optional?
In var node : SKNode? = SKNode.new(), node has to be explicitly defined as an optional because SKNode.new() will never return nil.
The goal of types in Swift is to guarantee that once a variable is defined, its type will never change, and the variable will always have valid data. Defining a variable as an optional (SKNode?) means the variable is an Optional<SKNode> which is NOT equivalent to SKNode (hence 'SKNode?.Type' does not have a member named 'new')
The error Binary operator '!=' cannot be applied to operands of type 'SKNode' and 'nil' that you are receiving is cause because you are trying to check if a non-optional value is Optional.None (or nil), which is a completely unnecessary (and impossible) check in the language.
We usually do things lik
- (void)setFoo:(Foo *)foo
{
_foo = foo;
// other computation
}
Getter and Setters give me warning that I cant set my own property. I am guessing it needs a computed property. What would be the best way to translate this idiom in Swift?
If you're doing computation tightly integrated with setting the internal storage of foo, especially if setting the storage is conditional on such computation, the computed-property/stored-property pair #matt suggests is probably the solution you need.
Otherwise—if you need to need to do work unconditionally in response to the setting of a property—what you're looking for is Swift's property observers feature.
var foo: Foo {
willSet(newFoo) {
// do work that happens before the internal storage changes
// use 'newFoo' to reference the value to be stored
}
didSet {
// do work that happens after the internal storage changes
// use 'oldValue' to reference the value from before the change
}
}
You can "shadow" a public computed variable with a stored private variable, like this:
private var _foo : Foo!
var foo : Foo {
get {
return _foo
}
set (newfoo) {
_foo = newfoo
}
}
That is the analogy to what Objective-C #synthesize does. But you should also ask yourself whether you really need this. In most cases, you don't.
OK, here's what I want to do :
Let's say I have an item, e.g. an NSTextField
Let's also say we want to bind its hidden value to a BOOL variable - that's easy.
Now, here's the twist :
I want to bind the hidden property to a check in the fashion of (someStringVariable == "Some String")
In a few words : set the element to hidden when someStringVariable is equal to some string.
How can I do that from within the IB? Is it doable?
Well, this is basically a duplicate of this question which I answered. But somebody other than the questioner has put a bounty on this one, so:
Entirely within IB? No.
You can bind to a string-typed property and then use a custom value transformer to convert that string to a boolean according to its equality to the desired value.
However, it's probably just easier to add a property to the class that has the string-typed property:
// Assumed to exist:
#property (copy) NSString* someStringProperty;
+ (NSSet*) keyPathsForValuesAffectingShouldBeHidden
{
return [NSSet setWithObject:#"someStringProperty"];
}
- (BOOL) shouldBeHidden
{
return [self.someStringProperty isEqualToString:#"desired string"];
}
Since this property is really part of the UI rather than the model, you may wish to define it in a category on the model class. The category itself would be declared and defined in the controller code.
Once it's defined, you can bind to the shouldBeHidden property.
You mean someting like this?
string1=string2 ? hidden=true : hidden=false
Is there any way to make a custom property required in QML? E.g., something like:
property required int numRows
I want to enforce that the user of the component passes a certain property, because the component will not work without it.
There is a required option was added in QT 5.15 qml: qt doc.
The syntax is the following:
required property <propertyType> <propertyName>
Thanks Marcin Orlowski for update
no, you can't. The most robust way is simply to give a valid default value to the property.
a workaround could be to give an invalid value (e.g -1) and check value in the Component.onCompleted slot of your item and show a console.log if property wasn't valid...
but prefer the first way, a component should always be usable with default values, for reusability goals!
Qt trolls have told themselves that Component.onCompleted is not the preferred way to do most things, but a hack the had to implement.
The best possible is to use a declarative-style enabler, something like this would be ideal:
MyItem{
property int myvalue: -1
enabled: myvalue != -1 // Use other number if neccesary
}
This would work for enabling interactive elements, but more interesting stuff can be made like:
MyItem{
property int myvalue: -1
onMyvalueChanged:{
enabled = true
callMyInitFunction(something)
}
}
That will trigger when the user changes the value, then you can call other functions or initializers. If you want to init only once, you can check if it's disabled.
MyItem{
property int myvalue: -1
onMyvalueChanged:{
if (!enabled){
enabled = true
callMyInitFunction(something)
return
}
// Stuff to do of already initialized
callOtherStuff(otherThing)
}
}
Finally, by reading the words you wrote "passes a certain property" it seems you might instead create a javascript function for the object and call it.
MyItem{
property int _myprop: 0
function launch(param1, param2, param3){
_myprop = param3
// do stuff
}
}
Then you would call it by launching it instead of creating it, this might work for a reusable Dialog, depends on your use case.
Of course there are several ways to do things depending on what you need.