Black Magic's Coming, don't blink.

Source: Internet
Author: User
Tags variable scope

Clang Attributes black Magic Little Memory

Clang Attributes is a source code annotation provided by Clang, which allows developers to express certain requirements to the compiler, participate in control such as Static Analyzer, Name mangling, code Generation and so on, generally In __attribute__(xxx) the form of code; for ease of use, some commonly used properties are also defined by COCOA macro, such as the NS_CLASS_AVAILABLE_IOS(9_0) __attribute__(availability(...)) simple notation of this property, which is often seen in the system header file.

A description of the common properties can be seen in Nshipster's introductory article and the Twitter introductory article. This article will also introduce a few interesting "black Magic" Attribute, perhaps in some scenarios will play an unexpected effect oh ~

The following tests are subject to Xcode 7.3 (Clang 3.8)

objc_subclassing_restricted

Use this property to define one Final Class , that is, a class that cannot be inherited, assuming that we have a Eunuch(太监) class named, but do not want someone to inherit from it:

@interface Eunuch:nsobject
@end
@interface Child:eunuch//eunuch can not have a child hit
@end

Just add this property before the @interface objc_subclassing_restricted :

__attribute__ ((objc_subclassing_restricted))
@interface Eunuch:nsobject
@end
@interface Child:eunuch//<---Compile Error
@end
Objc_requires_super

AKA: NS_REQUIRES_SUPER the flag subclass needs to be called when inheriting this method super , otherwise a compile warning is given:

@interface Father:nsobject
-(void) Hailhydra __attribute__ ((objc_requires_super));
@end
@implementation Father
-(void) Hailhydra {
NSLog (@ "Hail hydra!");
}
@end
@interface Son:father
@end
@implementation Son
-(void) Hailhydra {
}//<---Warning missing [super Hailhydra]
@end
Objc_boxable

The @(...) syntax sugar in objective-c can be an object of the basic data type NSNumber , and if you want to box a struct type or union type into an NSValue object, you can use this property:

typedef struct __ATTRIBUTE__ ((objc_boxable)) {
CGFloat x, y, width, height;
} Xxrect;

In this XXRect way, you have the ability to be box:

CGRect rect1 = {1, 2, 3, 4};
Nsvalue *value1 = @ (rect1); <---Compile Error
Xxrect Rect2 = {1, 2, 3, 4};
Nsvalue *value2 = @ (RECT2); √
Constructor/destructor

As the name implies, constructors and destructors, together with the functions of these two properties, are invoked at the time of the executable (or shared library)load and unload , which can be understood as main() executing before and after a function call:

__attribute__ ((constructor))
static void Beforemain (void) {
NSLog (@ "Beforemain");
}
__attribute__ ((destructor))
static void Aftermain (void) {
NSLog (@ "Aftermain");
}
int main (int argc, const char * argv[]) {
NSLog (@ "main");
return 0;
}

Console:
"Beforemain", "main", "Aftermain"

Constructor and +load both are called before the main function executes, but +load earlier than constructor, because DYLD (the dynamic linker, the original starting point of the program) notifies to load all of the classes, every time a class is loaded, it's +load called, and when it's all loaded, Dyld calls all the constructor methods in the image.

So constructor is a great time to do bad things:

    1. All classes have been loaded and completed
    2. The main function is not yet executed
    3. No need to be mounted in a Class like +load

FDStackViewThe Fdstackviewpatchentry method is to use this time to achieve the bogus trick.

PS: If there are multiple constructor and want to control the priority, it can be written __attribute__((constructor(101))) , the smaller the number of the priority, the higher the 1 ~ 100 for the system reservation.

Enable_if

This property can be used only on C functions, which allows static checking of parameters :

static void Printvalidage (int age)
__attribute__ ((enable_if > 0 && Age < 120, "You Ya Martian?" "))) {
printf ("%d", age);
}

It indicates that the function must be satisfied age > 0 && age < 120 before it is called to be allowed, and thus:

Printvalidage (26); √
Printvalidage (150); <---Compile Error
Printvalidage (-1); <---Compile Error
Cleanup

Declare to a variable, when this variable scope ends, call a specified function, reactive COCOA with this feature to achieve the Magic @onExit , about this attribute, in the previous article has introduced, the portal.

Overloadable

For C functions, you can define several methods with the same function name but different parameters, and the compiler will automatically select the function prototype according to the parameters when called:

__attribute__ ((overloadable)) void loganything (id obj) {
NSLog (@ "%@", obj);
}
__attribute__ ((overloadable)) void loganything (int number) {
NSLog (@ "%@", @ (number));
}
__attribute__ ((overloadable)) void loganything (CGRect rect) {
NSLog (@ "%@", Nsstringfromcgrect (rect));
}
Tests
Loganything (@[@ "1", @ "2"]);
Loganything (233);
Loganything (CGRectMake (1, 2, 3, 4));
Objc_runtime_name

For @interface or @protocol , specify the name of the class or protocol as another at compile time:

__ATTRIBUTE__ ((Objc_runtime_name ("Sarkgay")))
@interface Sark:nsobject
@end

NSLog (@ "%@", Nsstringfromclass ([Sark class])); "Sarkgay"

All places that directly use this class name are replaced (the only thing to be aware of is that this is not the case with reflection), and the simplest and most brutal thing to do is to confuse a class name:

__ATTRIBUTE__ ((Objc_runtime_name ("40EA43D7629D01E4B8D6289A132482D0DD5DF4FA")))
@interface Secretclass:nsobject
@end

Can also start with the numbers, afraid of fear--if you write a script to each class before adding a randomly generated objc_runtime_name , is not the most concise version of the code to complete the confusion ...

It is the only one I know of the OBJC runtime class structure has an impact on the attribute, by encoding the class name can be injected at compile time some information, is taken to the runtime, and then back out, which is equivalent to open a secret channel, the write code and run time. Brain hole, if this attribute definition macro, in annotation the form of the completion of certain functions, such as:

@singleton Wrapped Up __attribute__ ((Objc_runtime_name (...)))
Rename the class name to "Singleton_sark_sharedinstance"
@singleton (Sark, sharedinstance)
@interface Sark:nsobject
+ (instancetype) sharedinstance;
@end

At runtime, we use the runtime to __attribute__((constructor)) find this class, to solve the selector information of "sharedinstance", to replace it dynamically + alloc , and to return a - init + sharedInstance single case.

References

Http://llvm.org/releases/3.8.0/tools/clang/docs/AttributeReference.html
Http://clang-analyzer.llvm.org/annotations.html

Black Magic's Coming, don't blink.

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.