When Apple released Xcode7, it not only upgraded the SWIFT programming language to version 2.0, but also made many improvements to objective-c, including the introduction of __nonnull/__nullable. Among them, for the OBJECTIVE-C programming language itself, the more useful is the lightweight generics.
Among them, the more obvious embodiment is nsarray, nsdictionary these container classes have introduced the new lightweight generics. With lightweight generics, we can easily get the elements in them and access their photo-specific properties and methods. Let's give a simple example to illustrate the convenience of lightweight threading:
// case without generics
NSArray * numArray = @ [@ 10, @ 20, @ 30];
int sum = [(NSNumber *) numArray [0] intValue] + [(NSNumber *) numArray [1] intValue] + [(NSNumber *) numArray [2] intValue];
// When using generics
NSArray <NSNumber *> * numArray = @ [@ 10, @ 20, @ 30];
int sum = [numArray [0] intValue] + [numArray [1] intValue] + [numArray [2] intValue];
We can see from the above example the syntactic convenience of a lightweight generic, which is a sweet syntactic sugar (syntax sugar).
The previous generic--generic selection of the Apple LLVM 6.0 to the C11 standard was not well supported on objective-c, but Apple LLVM 7.0 has been able to support it perfectly. Examples are as follows:
int flag = _Generic(@100, NSNumber*:1, NSString*:2, int:3, default:0);
NSLog(@"The flag is: %d", flag);
The code above will successfully output "the flag is:1".
Unlike C11 's generic selection, the objective-c comes with a generic type of covariant, which is covariant. That is, its generics are similar to those of Java. It requires that the generic must be a objective-c class type, that is, the ID type at least. For the above Nsarray example, when declaring a Objective-c object reference, by adding <NSNumber*> after the class name to indicate that the element in the current Nsarray is a nsnumber* class or its subclass type. This allows us to access its Intvalue method directly when accessing its elements.
Here we describe how to define a generic class by itself. Its syntax is described as follows:
@interface class_name < __covariant Type_identifier > inherit_expression
Here,class_name is the class name;type_identifier is a type identifier that can be named by the programmer himself; the last inherit_expression Represents inheriting a parent class and/or implementing some protocol.
A new keyword,__covariant, is introduced here, indicating that the following Type_identifier is a generic type. The generic type is specifically specified when declaring an object.
Here is a concrete example of how to use the Objective-c generics specifically.
@interface MyObject<__covariant T> : NSObject
{
@private
T obj;
}
@property (nonatomic, retain) T obj;
@end @implementation myobject@synthesize obj;
@end
@implementation MyObject
@synthesize obj; - (void)dealloc
{ if(obj != nil)
[obj release];
NSLog(@"My object deallocated!");
[super dealloc];
}
@end
@implementation ViewController - (void)viewDidLoad {
MyObject<NSNumber*> *numObj = [[MyObject alloc] init];
numObj.obj = @100;
[numObj release];
MyObject<NSString*> *strObj = [[MyObject alloc] init];
strObj.obj = @"Hello, world";
[strObj release];
}
@end
In the above code, we define a MyObject generic class whose generic identifier is represented by T. We then define a private object, obj, with the generic T and use it as a property.
Subsequently, we declared an object numobj with myobject<nsnumber*> in the Viewdidload method, and declared a Strobj object with myobject<nsstring*>. We can then call Intvalue directly from numobj.obj to access its int value, and call the length method directly through Strobj.obj to get its string lengths.
Objective-c Lightweight generics