Because of the many exciting new features of Swift 3.0, it is easy to overlook minor changes in objective-c. Perhaps you would think that Apple's mention of objective-c is probably to improve and swift interoperability (translator note: The main point of interoperability is the OC code and the SWIFT code to convert each other), but Apple is still welcome developers to use OBJECTIVE-C to complete the work.
In this article, let's take a look at the newly added class properties in Objective-c.
Objective-c class Properties
Excerpt from the official version of Xcode 8:
Objective-c now supports class properties, which interoperate with Swift type properties.
They is declared as: @property (Class) NSString *somestringproperty;.
They is never synthesized. (23891898)
Translate as follows:
Objective-c now supports the class attribute, which corresponds to the Type property of Swift for the class attribute in OC.
They are stated as follows: @property (Class) NSString *somestringproperty;
Class properties are never automatically synthesized.
To practice, let's create a simple Objective-c class that contains several types. This is our ' User ' class interface, which looks like this:
12345 |
@interface User : NSObject@property (class, nonatomic, assign, readonly) NSInteger userCount;@property (class, nonatomic, copy) NSUUID *identifier;+ (void)resetIdentifier;@end |
Here is a description of our two class properties, the first is a read-only integer type, and the second is a readable writable nsuuid type with the copy attribute. Be aware of classes that have attribute declarations.
Implementation is also very simple, we first need to store the ' identifier ' and ' UserCount ' class properties. Because they are class-level and not instance variables, we declare them static:
|
@implementation Userstatic NSUUID *_identifier = nil;static NSInteger _userCount = 0; |
Now we have to create a ' getter ' and ' setter ' method for both attributes. As already mentioned in the release notes, these class attributes are never synthesized, so Xcode will report a warning if a ' getter ' or ' setter ' is missing. The first read-only ' UserCount ' requires only a getter method that returns the Count value. Note that using ' + ' turns our getter method into a class method:
|
+ (NSInteger)userCount { return_userCount;} |
The ' identifier ' property is required for both getter and setter methods. In the Getter method, if identifier is empty, we create a new identifier:
|
+ (NSUUID *)identifier { if(_identifier == nil) { _identifier = [[NSUUID alloc] init]; } return_identifier;}+ (void)setIdentifier:(NSUUID *)newIdentifier { if(newIdentifier != _identifier) { _identifier = [newIdentifier copy]; }} |
We have also created a basic initialization method for the ' User ' class that will update the Count property.
|
- (instancetype)init{ self = [superinit]; if(self) { _userCount += 1; } returnself;} |
The ' Resetidentifier ' class method is a convenient way to create a new identifier:
|
+ (void)resetIdentifier { _identifier = [[NSUUID alloc] init];}@end |
We can use point syntax after the class name to get to the class property:
User.usercount;
User.identifier;
Here is an example of the user class usage:
|
for(int i = 0; i < 3; i++) { self.user = [[User alloc] init]; NSLog(@"User count: %ld",(long)User.userCount); NSLog(@"Identifier = %@",User.identifier);}[User resetIdentifier]; NSLog(@"Identifier = %@",User.identifier); |
Here is the output:
|
// User count: 1// Identifier = 4B98B7FD-F8DC-484A-92B2-B2BB20BCB709// User count: 2// Identifier = 4B98B7FD-F8DC-484A-92B2-B2BB20BCB709// User count: 3// Identifier = 4B98B7FD-F8DC-484A-92B2-B2BB20BCB709// Identifier = A0519681-1E08-4DF2-B2D1-D077CF2BDEFF |
Note: Although this is a new feature of the LLVM compiler in Xcode 8, it still works for versions prior to iOS 10.
The generated Swift interface
It seems that the recent improvements in objective-c are just to improve interoperability with Swift. The newly added type attribute in objective-c corresponds to the use of class variables in Swift. Here's what we'll look like after we've converted the ' User ' class to Swift:
|
PUBLIC&NBSP;CLASS&NBSP;USER&NBSP;:&NBSP;NSOBJECT&NBSP;{&NBSP;&NBSP;&NBSP;PUBLIC&NBSP;CLASS&NBSP;var USERCOUNT:&NBSP;INT&NBSP;{&NBSP;GET&NBSP;}&NBSP;&NBSP;PUBLIC&NBSP;CLASS&NBSP;var IDENTIFIER:&NBSP;UUID!&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;public class func resetidentifier ()} |
Note that the identifier Class property is an implicitly unpacked variable, meaning we never want it to be nil. To allow it to be nil, we need to add a ' nullable ' identifier to the OBJECTIVE-C attribute declaration. Our Swift variable will also be of an optional type. See [Using nullable to annotate objective-c] for more details.
Expand Reading
WWDC Session 405 What's New in LLVM
Swift 3.0 is exciting, but Objective-c also has small improvements--objective-c class properties