Swift - is there a short hand property like Objective-C? - swift

I am trying to see if there is a short-hand way to write the following using Swift.
#property (nonatomic, strong) UIColor* circleColor
I have read through the documentation and I can't seem to find a way to shorten properties in general without having to writing both the setters and/or getters.

The equivalent of that in Swift would be this:
var circleColor:UIColor
which is actually a good deal shorter than the ObjC version. Swift somewhat merges the concepts of properties and instance variables.
If you need 'nil' to be a possible value for circleColor, then use 'UIColor?' instead of 'UIColor'.

I'm posting this answer to raise the visibility of #JackWu's comment - the way this should be done is:
var circleColor: UIColor!
The implicitly-unwrapped version is the recommended way and more closely represents how object properties work in Obj-C right now (i.e. the fact that they begin life as nil once declared).

Related

Why do properties modified by #optional become immutable?

I have an Objective-C protocol that contains a property as follows:
#import <Foundation/Foundation.h>
#protocol Playback <NSObject>
#optional
#property (nonatomic, nonnull) NSURL *assetURL;
#end
PlayerController has a property of type id<Playback>:
#interface PlayerController: NSObject
#property (nonatomic, strong, nonnull) id<Playback> currentPlayerManager;
#end
I tried to write the following code in Swift, but I got an error:
var player = PlayerController()
var pla = player.currentPlayerManager
pla.assetURL = URL(string: "123") // ❌ Cannot assign to property: 'pla' is immutable
If I comment out the #optional for the Playback protocol, then it compiles fine.
This makes me wonder why #optional would cause this error?
From Jordan Rose (who worked on Swift at the time that SE-0070 was implemented) on the forums:
Normally optional requirements add an extra level of optionality:
Methods become optional themselves (f.bar?())
Property getters wrap the value in an extra level of Optional (if let bar = f.bar)
But there's nowhere to put that extra level of Optional for a property setter. That's really the entire story: we never figured out how to expose optional property setters in a safe way, and didn't want to pick any particular unsafe solution. If someone can think of something that'd be great!
So the answer appears to be: at the time that optional protocol requirements were intentionally limited to Objective-C protocols in Swift (SE-0070), no spelling for an explicit implementation of this was decided on, and it appears that this functionality is uncommon enough that this hasn't really come up since.
Until (and if) this is supported, there are two potential workarounds:
Introduce an explicit method to Playback which assigns a value to assetURL
Sadly, this method cannot be named -setAssetURL: because it will be imported into Swift as if it were the property setter instead of a method, and you still won't be able to call it. (This is still true if you mark assetURL as readonly)
Also sadly, this method won't be able to have a default implementation, since Objective-C doesn't support default protocol implementations, and you can't give the method an implementation in a Swift extension because you still can't assign to the protocol
Do like you would in Swift and introduce a protocol hierarchy, where, for example, an AssetBackedPlayback protocol inherits from Playback and offers assetURL as a non-#optional-property instead:
#protocol Playback <NSObject>
// Playback methods
#end
#protocol AssetBackedPlayback: Playback
#property (nonatomic, nonnull) NSURL *assetURL;
#end
You would then need to find a way to expose PlayerController.currentPlayerManager as an AssetBackedPlayback in order to assign the assetURL.
Some additional alternatives from Jordan:
I think the original recommended workaround was "write a static inline function in Objective-C to do it for you", but that's not wonderful either. setValue(_:forKey:) can also be good enough in practice if it's not in a hot path.
The static inline function recommendation can function similarly to a default protocol implementation, but you do need to remember to call that function instead of accessing the property directly.
setValue(_:forKey:) will also work, but incurs a noticeable performance penalty because it supports a lot of dynamism through the Objective-C runtime, and is significantly more complicated than a simple assignment. Depending on your use-case, the cost may be acceptable in order to avoid complexity!
Since it's optional, Swift can't guarantee the setter is implemented.

When to use #property? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why should I use #properties?
When to use properties in objective C?
I have been programming in objective-c for a little over a year now, and I always felt like it was a convention to use #property and #synthesize. But what purpose do they really serve ? Are they solely there to be communicated between classes ? So, for instance, if I use an NSMutableDictionary only in the scope of the class where it was declared, an omission is O.K. ?
Another question:
If I set the property of an NSMutableDictionary, it is retained, right ? So, in my class I don't have to call alloc() and init(), do I ?
What are the rules to use properties ?
But what purpose do they really serve?
Access control to iVars and abstraction between representation and underlying data.
Are they solely there to be communicated between classes?
No, they are for when you want to control access to iVars instead of accessing them directly or when you could in the future change underlying data structures but wish to keep the current representation.
So, for instance, if I use an NSMutableDictionary only in the scope of the class where it was declared, an omission is O.K.?
It depends. Do you want to have controlled access to the iVar? Would it be possible for your code to change so the dictionary is fetched and not a direct iVar. Usually, the answer is yes.
If I set the property of an NSMutableDictionary, it is retained, right?
Depends on how you declare the property.
So, in my class I don't have to call alloc() and init(), do I?
You have sloppy wording here. I think you are asking if you still need to construct an instance of a property. Yes, you will need to construct an instance of a property in some way. There are lots of ways of doing this.
NOTE: the convention for talking about methods is use their signature. Instead of alloc(), you would use -alloc.
What are the rules to use properties?
This you will need to read the doc for.
Like in another languages, when we want to make our variable global or public we use public access modifier. In objective c when we want access our another class variable in other class, we use #property and #synthesize them. Basically #synthesize is way by which compiler create a setter and getter methods for that variable. You can manually create them but not use #synthesize.
By creating object of that class you can access your property variable in other class.
By using retain, you clear that is take place memory and not exist until that container class not goes dispose or released.
Properties simply make your life easier.
Nowadays use properties as much as you can in terms of memory management, code-style and timesaving.
What do #propertys do?
They can create getter and setter methods (depends on given parameters).
Normally you declare instance variables in the header file (like in c++).
Now you simply let that be and instead of that declare the properties you want for instance variables.
Properties can get multiple arguments.
For normal objective-c objects, where you need a pointer (*) you would write.
#property (nonatomic,retain,...)
When you #synthesize it it creates a getter and a setter.
The setter automatically does stuff like releasing your old object, that your variable hold and retaining the new one.
So you don't have to do that manually (which should be quite often the case). Thats important.
You also can give it arguments (readonly,readwrite) to decide if to set a setter or not.
You can even declare a #property in the header file readonly and override that in your implementation file with a extension (a category with no name).
To dive deeper into this, read the apple developer manuals, which are quite effective.
Hope that helps a bit.
Shure it is the tip of the iceberg, but it's mostly everything you need.

Internal properties versus ivars

When I need a private object I currently use properties, like so:
// Class extension in .m file
#interface MyClass()
#property (strong, nonatomic) NSArray* myInternalArray;
#end
self.myInternalArray = something;
Alternatively you can do this:
#implementation MyClass {
NSArray* _myInternalArray;
}
_myInternalArray = something;
Without a custom setter or getter the two are equivalent. What is the best practice for internal variables? Are there any advantages of one method over the other?
While some may argue that the choice is a matter of preference, and they do have a point, there is a very good reason that most modern languages support properties and make them easier and easier to code.
The introduction of ARC does not significantly reduce the value of properties. It all comes down to this - in a property you have encapsulated the use of a variable. That encapsulation is invaluable when needed, and not much overhead when it is not.
For example (off of the top of my head) Suppose you discovered that you needed to validate the value before saving it. If you were using an iVar, you would have to ensure that anywhere that iVar was used, you had a call the validation code before you allowed it's value to be changed. With a property, you would only need to override setIVarName: and put the validation there. One could argue that one is just as easy as the other - and that may be true in many cases, but there is one handicap with the iVar here - you cannot ensure that future changes (by you or other coders) will insert the validation before the iVar is changed. Using a property here does have that assurance.
Personally, I use properties over iVars where ever possible.
I'd say that the advantage of properties is that you would use setters, and that setters can evolve independently of the code that call them. For instance, you could decide that setting a property would now trigger setNeedsLayout. By using properties from the start, you would have no need to refactor existing code.
This pattern fits very well in Cocoa/iOS APIs, where you don't have to ask system objects to do anything after having changed their properties: setters ensure internal and UI consistency right away.
The fact that properties are private should not make us implement them as second-class properties, what do you think?

Defining members and properties in Xcode 4 & iOS 4

I am fairly far along developing a reasonably ambitious first iPhone project and I am confused as to which way to implement and access properties and why.
Example 1:
(in the .h)
Nsstring *_sale;
#property (nonatomic, retain) NSString *sale;
(in the .m)
#synthesize sale = _sale;
Example 2:
(in the .h)
#property (nonatomic, retain) NSString *sale;
(in the .m)
#synthesize sale;
Both of these seem to work to me without trouble but I am trying to figure out why there are two ways to do this and what benefits there may be to either.
Can someone tell me the difference?
Example 1 demonstrates the old way of defining ivar/property variable pairs. The new compiler now generates ivars (the NSstring *_sale; part) for you. Example 1 also demonstrates manually pairing up the property sale to the ivar _sale using the #synthesize sale = _sale; statement.
Example 2 is a more concise way to implement properties in Obj-C and is the way you will see most example code on the internet. The vast majority of the time you can write your properties without needing to overwrite the accessor/mutator methods generated for you by the compiler.
There are some die-hard proponents of the underscore prefix to denote instance variables for clarity's sake. You may find that this helps you when it comes to memory management, as in Example 1, setting self.sale equal to an autoreleased NSString would be fine since it would get retained, but setting _sale equal to an autoreleased object would result in erratic behavior later on because the NSString passed in would not be retained by the instance variable.
In general, I prefer writing my properties as you have shown in Example 2.
Short Answer: There are two ways of doing this because the new compiler now can infer some stuff for you, but the previous way of doing things has been left in for backwards compatibility.
They both work the same way. Some people prefix their instance variable with an underscore as a visual cue to differentiate member variables from instance variables.
More discussion at this SO question: How does an underscore in front of a variable in a cocoa objective-c class work?
For more Cocoa style guidelines checkout CocoaDevCentral.

Why use 'self.' when its not forced?

I noticed a difference between the way I code (badly ;) ) and the code I see from others.
Can anybody explain why I see some people using
self.varname.anotherpropertie
When
varname.anotherpropertie
Seems to work just as well. I dont use self. a lot in my code. I'm wondering is this very bad or is there something that I need to learn to understand why its used so much by most people?
Thanks again,
-Code
They are different things. In a class where you have an instance variable named foo with a declared property also named foo, writing simply foo accesses the instance variable while self.foo goes through the getter method for the property (which might just return the instance variable or it might do more).
I'd suggest taking a look at the Declared Properties chapter of Apple's The Objective-C Programming Language for a full explanation of how it works and when to choose which option.
One gotcha that I've run into is the retain vs non-retain with properties.
So if you have a retained property like this:
#property (nonatomic, retain) NSString* myStr;
#synchronized myStr;
and you do something like this:
- (void) myMethod:(NSString*)inStr
{
myStr = inStr;
}
In this example you will not actually retain the string as your property is not invoked. If you change the assignment line to use the property (by using "self.") then the string would be retained (and the previous string would be released if non-nil).
self.myStr = inStr;
It takes some getting used to that properties are method calls, but once you start seeing them as such then the "self." syntax becomes much more clear. Hope that helps some.