attribute is one of the GNU C features and is widely used in iOS. There are many places to use in the system. attribute can set function attributes (functions attribute), variable attributes (Variable attribute), and type attributes. Function Properties Attribute) noreturn noinline always_inline Pure const nothrow Sentinel format Format_arg no_instrument_function sect Ion constructor destructor used unused deprecated weak malloc alias Warn_unused_result nonnull Type properties (Type Attributes) aligned packed transparent_union, unused, deprecated may_alias variable attributes (Variable attribute) aligned packed C Lang-specific availability overloadable writing format
Writing format: After theattribute will be followed by a pair of original brackets, brackets inside the corresponding attribute parameters
__attribute__ (XXX)
Common system Usage
format
Official Example: NSLog
#define Ns_format_function (F,a) __attribute__ (FORMAT (__nsstring__, F, A))
The Format property can add a feature like printf or scanf to the declared function, which enables the compiler to check whether the formatted string between the function declaration and the actual call parameter of the function matches. This feature is useful, especially when dealing with bugs that are hard to find. The following is used for the format parameter
Format (archetype, String-index, First-to-check)
The first parameter needs to be passed "archetype" specifies which style, here is nsstring; "String-index" specifies that the first parameter of the Passed-in function is a formatted string, and "First-to-check" specifies the index in which it is located. Noreturn
Official example: Abort () and exit ()
This property notifies the compiler that the function never returns a value. This property avoids error messages when a similar function is encountered that needs to be exited before it is run to the return statement. Availability
Official Example:
-(Cgsize) Sizewithfont: (Uifont *) font Ns_deprecated_ios (2_0, 7_0, "use-sizewithattributes:") __tvos_prohibited;
Look at the macro behind
#define Ns_deprecated_ios (_iosintro, _IOSDEP, ...) Cf_deprecated_ios (_iosintro, _IOSDEP, __va_args__) define Cf_deprecated_ios
(_iosintro, _IOSDEP, ...) __attribute __ ((Availability (ios,introduced=_iosintro,deprecated=_iosdep,message= "__va_args__)")
//Macro expansion following
__ ATTRIBUTE__ ((Availability (ios,introduced=2_0,deprecated=7_0,message= "__va_args__)");
iOS is the iOS platform
//introduced from which version to start using
//deprecated from which version to discard the//message warning message
The Availability property is a comma-delimited list of arguments, starting with the name of the platform, containing some landmark declarations placed in additional information.
Introduced: The first occurrence of the version.
Deprecated: Declaring a version to be discarded means that the user is migrating to another API
Obsoleted: Declares the removed version, meaning that it is completely removed and can no longer be used
Unavailable: Not available on these platforms
Message: Some additional information about scrap and removal, which is provided by Clang when issuing a warning, is useful for users using an alternative API.
The platform supported by this property: Ios,macosx.
Simple example:
If used frequently, it is recommended to define a system
-like macro-(void) Oldmethod: (NSString *) string __attribute__ (Availability (IOS,INTRODUCED=2_0, Deprecated=7_0,message= "Use-newmethod: This method replaces")) {
NSLog (@ "I am the old way, don't tune Me");
}
-(void) Newmethod: (NSString *) string{
NSLog (@ "I am new Method");
}
Effect:
Paste_image.png
If invoked, there will be a warning
Paste_image.png unavailable
Tells the compiler that the method is not available and prompts an error if the compiler is forced to invoke it. For example, when a class is constructed, it does not want to initialize it directly through INIT, it can mark the Init method as unavailable only through a specific initialization method (), such as a single example;
The macro of the system can be directly used to
#define Unavailable_attribute __attribute__ (unavailable)
#define Ns_unavailable Unavailable_attribute
@interface person:nsobject
@property (nonatomic,copy) nsstring *name;
@property (nonatomic,assign) Nsuinteger age;
-(instancetype) init ns_unavailable;
-(Instancetype) Initwithname: (NSString *) name Age: (Nsuinteger) age;
@end
Paste_image.png
In fact, unavailable can be followed by parameters, showing some information, such as:
The system
#define Ns_automated_refcount_unavailable __attribute__ (unavailable ("Not available in automatic reference Counting Mode "))
Objc_root_class
Indicates that the class is a root class (base class), such as Nsobject,nsproxy.
Excerpt from System
//nsproxy
ns_root_class
@interface nsproxy <NSObject> {
CLASS Isa;
}
NSObject
__osx_available_starting (__mac_10_0, __iphone_2_0)
objc_root_class
objc_export
@ Interface NSObject <NSObject> {
Class isa objc_isa_availability;
}
NSObject
@property (Nonatomic,strong) __attribute__ ((nsobject)) Cfdictionaryref mydictionary;
Cfdictionaryref belongs to the Corefoundation framework, that is, non-OC objects, plus attribute((nsobject)), MyDictionary memory management will be treated as an OC object. Objc_designated_initializer
The designated initializer initialization method that is used to modify the class, if the modified method does not call the Super class's designated initializer, the compiler warns. can be abbreviated as Ns_designated_initializer
This article is very good, it is recommended to refer to this.
https://yq.aliyun.com/articles/5847 Visibility
Grammar:
__ATTRIBUTE__ ((Visibility ("Visibility_type"))
Where Visibility_type is one of the following values:
Default
The assumed symbolic visibility can be changed by other options. The default visibility overrides this type of change. The default visibility corresponds to an external link.
Hidden
The symbol is not stored in the dynamic symbol table, so no other executable file or shared library can refer to it directly. Use function pointers to make indirect references.
Internal
Unless specified by the processor-specific application binary interface (Psabi), internal visibility means that the function is not allowed to be called from another module.
Protected
The symbol is stored in the dynamic symbol table, but the references within the definition module are bound to the local symbol. In other words, the symbol cannot be overwritten by another module.
In addition to specifying default visibility, this property can be used in conjunction with a declaration that has an external link in those cases.
You can use this property in C and C + +. In C + +, it can also be applied to types, member functions, and namespace declarations.
System usage:
uikit_extern extern
#ifdef __cplusplus
#define Uikit_extern extern "C" __attribute__ ( Visibility ("default"))
#else
#define Uikit_extern EXTERN __attribute__ ((Visibility ("default"))
#endif
'
nonnull
The compiler checks for null on function arguments, which must be pointer types (including objects)
Use
-(int) ADDNUM1: (int *) NUM1 num2: (int *) num2 __attribute__ ((nonnull (1,2)) {//1,2 indicates that the first and second arguments cannot be null return *num1 + *num2;
}
-(NSString *) GetHost: (nsurl *) URL __attribute__ ((nonnull (1)) {//The first parameter cannot be an empty return
url.host;
}
Common usage
aligned
__attribute ((aligned (n)) to align the member of the structure to the N-byte natural boundary. If the length of a member in the structure is greater than N, it is aligned according to the length of the maximum member. For example:
The situation without modification
typedef struct
{
char member1;
int member2;
Short Member3;
} Family;
Output bytes:
NSLog (@ "Family size is%zd", sizeof (Family));
Output:
2016-07-25 10:28:45.380 study[917:436064] Family size is 12
Modify byte alignment to 1
typedef struct
{
char member1;
int member2;
Short Member3;
} __ATTRIBUTE__ ((Aligned (1))) Family;
Output bytes:
NSLog (@ "Family size is%zd", sizeof (Family));
Output:
2016-07-25 10:28:05.315 study[914:435764] Family size is 12
Consistent with the results above, because the set byte alignment is 1. The maximum number of bytes in the structure is int 4 bytes, 1 < 4, aligned to 4 bytes, and the system defaults in line.
Modify byte alignment to 8
typedef struct
{
char member1;
int member2;
Short Member3;
} __ATTRIBUTE__ ((Aligned (8))) Family;
Output bytes:
NSLog (@ "Family size is%zd", sizeof (Family));
Output:
2016-07-25 10:28:05.315 study[914:435764] Family size is 16
Here 8 > 4, according to the 8 byte alignment, the result is 16, do not know byte alignment can see my article http://www.jianshu.com/p/f69652c7df99
But thought for a long time, also do not know what the use of this thing, set the value is less than the default system, and did not set the same, set the big, and waste space, efficiency did not improve, feel learning and learning good. packed
To align the specified structure body by one byte, test:
Modify the
typedef struct {
char version without packed ;
int16_t SID;
int32_t Len;
int64_t time;
} Header;
Calculates the length
NSLog (@ "size is%zd", sizeof (Header));
Output:
2016-07-22 11:53:47.728 study[14378:5523450] size is 16
As you can see, the default system is aligned with 4 bytes
Add packed modifier
typedef struct {
char version;
int16_t SID;
int32_t Len;
int64_t time;
} __ATTRIBUTE__ ((packed)) Header;
Calculates the length
NSLog (@ "size is%zd", sizeof (Header));
Output:
2016-07-22 11:57:46.970 study[14382:5524502] size is 15
After being decorated with packed, it becomes 1-byte alignment, which is commonly used in protocol-related network transmissions. Noinline & Always_inline
inline function: The inline function from the source code layer, there is a function of the structure, but in the compilation, but does not have the nature of the function. Instead of a control transfer at the time of the call, the inline function embeds the function body at every call at compile time. At compile time, similar to macro substitution, use function body to replace function name at call. Generally in the code with inline modification, but whether the formation of inline functions, you need to see the compiler on the definition of the function of the specific processing noinline not inline always_inline always inline these two are used on the function
The essence of inline is to replace the function call directly with the code block, the advantage is: Fast code execution, reduce system overhead. Applicable scenario: This function is smaller this function is not often called
Use examples:
function declares
void test (int a) __attribute__ ((Always_inline));
Warn_unused_result
When the return value of a function or method is important, the caller must check or use the return value, or the compiler will issue a warning message
-(BOOL) availiable __attribute__ ((warn_unused_result))
{return
;
}
Warnings are as follows:
Paste_image.png objc_subclassing_restricted
For some reason, we do not want this class to be inherited, that is, the "final" class, as follows:
__attribute__ ((objc_subclassing_restricted))
@interface Viewcontroller:uiviewcontroller
@end
If you inherit this class, the compiler will make an error.
Paste_image.png Objc_requires_super
This property requires a subclass to override the parent class method, which is to call the Super method, or warn if it overrides the parent class's method. Examples are as follows:
@interface Viewcontroller:uiviewcontroller
-(void) Jump __attribute__ ((objc_requires_super));
@end
-(void) jump{
NSLog (@ "Parent class must be executed first")
;
@interface sgviewcontroller:viewcontroller
@end
@implementation sgviewcontroller
-(void) jump{
NSLog (@ "Subclass can be executed again");
}
@end
Warnings are as follows:
Paste_image.png objc_boxable
Implement fast packaging capabilities like NSNumber @ (...), generally for struct,union we can only package it through Nsvalue. Objc_boxable can help us implement fast packaging, examples are as follows:
Custom structural body
typedef struct __ATTRIBUTE__ ((objc_boxable)) {
cgfloat x,y,width,height;
} Sgrect;
Sgrect rect = {0,0,100,200};
Here directly packaged into Nsvalue
nsvalue *value = @ (rect);
Here I print
NSLog (@ "%@", Nsstringfromcgrect) directly using the System method (value. Cgrectvalue));
Output:
2016-07-21 21:28:43.538 study[14118:5408921] {0, 0}, {100, 200}}
This allows Sgrect to be packaged quickly. Constructor/destructor
Constructor and destructor; constructor decorated functions are executed before the main function, and destructor decorated functions are called before the program exit.
Examples are as follows:
int main (int argc, char * argv[]) {
@autoreleasepool {
NSLog (@ "main");
Return Uiapplicationmain (argc, argv, Nil, Nsstringfromclass ([Appdelegate class]);
}
__attribute__ ((constructor))
void before () {
NSLog (@ "before main");
}
__attribute__ ((destructor))
void after () {
NSLog (@ "after main");
}
Call Exit
-(void) viewdidload {
[super viewdidload] in Viewcontroller;
Exit (0);
}
The output is as follows:
2016-07-21 21:49:17.446 study[14162:5415982] before main 2016-07-21 21:49:17.447 study[14162:5415982
] Main
2016-07-21 21:49:17.534 study[14162:5415982] after main
Note: When the program exits, it will call after function, after testing, the manual exit program will execute the above two functions no matter what class, which file in which the effect is the same if there are multiple decorated functions, then will be executed, the sequence is uncertain
In fact, if you have more than one modified function, you can adjust their precedence
The code is as follows:
int main (int argc, char * argv[]) {
@autoreleasepool {
NSLog (@ "main");
Return Uiapplicationmain (argc, argv, Nil, Nsstringfromclass ([Appdelegate class]);
}
__attribute__ (Constructor ())
void before1 () {
NSLog (@ "before main-1");
}
__attribute__ (Constructor (102))
void Before2 () {
NSLog (@ "before main-2");
}
__ATTRIBUTE__ (destructor (201))
void after1 () {
NSLog (@ "after Main-1");
}
__attribute__ (destructor ())
void after2 () {
NSLog (@ "after Main-2");
}
The output results are as follows:
2016-07-21 21:59:35.622 study[14171:5418393] before main-1 2016-07-21 21:59:35.624
14171:5418393] before main-2
2016-07-21 21:59:35.624 study[14171:5418393] main
2016-07-21 21:59:35.704 STUDY[14171:5418393] After the main-2
2016-07-21 21:59:35.704 study[14171:5418393] after main-1
Note: The values in parentheses denote precedence, and [0,100] This return is reserved by the system and must not be invoked by itself. According to the output, we can see that before the main function, the smaller the number, the more first call, the larger the number after the main function, the more the first call.
When the function declaration and function implementation are written separately, the format is as follows:
static void Before () __attribute__ ((constructor));
static void before () {
printf ("before\n");
}
Discussion: +load,constructor,main Order of execution, code as follows:
+ (void) load{
NSLog (@ "load");
}
__attribute__ ((constructor))
void before () {
NSLog (@ "before main");
}
The output is as follows:
2016-07-21 22:13:58.591 study[14185:5421811] Load
2016-07-21 22:13:58.592 study[14185:5421811] Before main
2016-07-21 22:13:58.592 study[14185:5421811] Main
You can see that the order of execution is:
Load->constructor->main
Why, then?
Because DYLD (dynamic linker, the beginning of the program) in the load image (can be understood as Mach-o file) will first notify the OBJC runtime to load all of the classes, each load a class, its +load with the call, all load complete, DYLD will call this IM All the constructor methods in age before calling the main function. enable_if
Used to check if the argument is legitimate and can only be used to modify the function:
void printage (int age)
__attribute__ (enable_if (age > 0 && Age < 120, "You ya Eunuch?"
)) {
NSLog (@ "%d", age);
}
Indicates that only the parameters can be entered can only be 0 ~ 120, or compile an error
The error is as follows:
Paste_image.png Cleanup
Declared on a variable, when the variable scope ends, the specified function is invoked. If you don't know what the scope is, learn about it first. Example:
The arguments passed here are the address
void intcleanup (int *num) {
NSLog (@ "cleanup------%d", *num) of
the variable
; -(void) test{
int a __attribute__ (Cleanup (intcleanup)) = ten;
}
The output is:
2016-07-22 09:59:09.139 study[14293:5495713] cleanup------10
Note: The parameter passed by the specified function is the end of the address scope of the variable including: curly braces end, return, Goto, break, exception, etc. when there are multiple cleanup variables in the scope, follow the stack structure that comes in first.
Sample code:
void Intcleanup (int *num) {
NSLog (@ "cleanup------%d", *num);
}
void Stringcleanup (NSString **str) {
NSLog (@ "cleanup------%@", *str);
}
void Rectcleanup (CGRect *rect) {
CGRect temp = *rect;
NSString *str = nsstringfromcgrect (temp);
NSLog (@ "cleanup------%@", str);
}
int a __attribute__ ((Cleanup (intcleanup)) = ten;
{
nsstring *string __attribute__ ((Cleanup (stringcleanup)) = @ "string";
CGRect rect __attribute__ ((Cleanup (rectcleanup)) = {0,0,1,1};
}
Output is:
2016-07-22 10:09:36.621 study[14308:5498861] cleanup------{0, 0}, {1, 1}}
2016-07-22 10:09:36.622 study[14308:5498861] Cleanup------string
2016-07-22 10:09:36.622 study[14308:5498861] cleanup------10
Discussion: If an object is modified, then cleanup and Dealloc, who executes first?
The test code is as follows:
void Objectcleanup (NSObject **obj) {
NSLog (@ "cleanup------%@", *obj);
}
-(void) viewdidload {
[super viewdidload];
Viewcontroller *VC __attribute__ ((Cleanup (objectcleanup)) = [[Viewcontroller alloc] init];
}
-(void) dealloc{
NSLog (@ "Dealloc");
}
The output results are as follows:
2016-07-22 10:23:08.839 study[14319:5502769] cleanup------<ViewController:0x13fe881e0>
2016-07-22 10:23:08.840 study[14319:5502769] Dealloc
It is obvious that cleanup before the object Dealloc execution. Usage in block: Use in block, first look at examples:
Pointer to block, feel bad understanding can be typeof
void Blockcleanup (void (^*block) ()) {
(*block) ();
}
void (^block) (void) __attribute__ (Cleanup (blockcleanup)) = ^{
NSLog (@ "Finish block");
The advantage is that you don't have to wait until the block finally writes some code, so we can put it anywhere in the block to prevent it from being forgotten. overloadable
For the C language function, you can define several functions with the same name, but with different parameters, the compiler will automatically select the function prototype based on the parameters when invoked:
__attribute__ ((overloadable)) void print (NSString *string) {
NSLog (@ "%@", string);
__attribute__ ((overloadable)) void print (int num) {
NSLog (@ "%d", num);
}
Call
print (ten);
Print (@ "haha");
Objc_runtime_name
See runtime is not feel tall, yes this is also related to the runtime. The function is to specify the name of the class or protocol as another at compile time. The example is as follows:
__ATTRIBUTE__ ((Objc_runtime_name ("NSObject"))
@interface sgobject:nsobject
@end
//Call
NSLog ( @ "%@", [Sgobject class]);
Output
2016-07-22 11:18:00.934 study[14355:5516261] NSObject
Can be used to do code obfuscation.
More Please reader network:
Https://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html
Reproduced from: http://www.jianshu.com/p/29eb7b5c8b2d