__ATTRIBUTE__ Summary __jni

Source: Internet
Author: User
Tags deprecated function prototype variable scope

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.