__attribute__ not commonly used in ios

1. Write a class and don’t want it to be inherited by subclasses [modified class]

__attribute((objc_subclassing_restricted))__

#import <UIKit/UIKit.h>
#import <objc/runtime.h>

NS_ASSUME_NONNULL_BEGIN

__attribute__((objc_subclassing_restricted))//禁止该类被继承
@interface AAA : UIView
-(void)mustUseMethod;
@end


NS_ASSUME_NONNULL_END

2. Prompt that the subclass must call the parent class method [modification method]

__attribute__((objc_requires_super))Add it after the method of the parent class, then the subclass must implement [super thisMethod] to call the method, otherwise a yellow warning will be issued

@interface Father : NSObject
- (void)mustUseMethod __attribute__((objc_requires_super)); 
@end

@interface Child : TestObject
@end

@implementation BBB
-(void)mustUseMethod{
    
    
 //[super mustUseMethod];
    警告信息:(不报错)
Method possibly missing a [super mustUseMethod] call
}
@end

3. constructor / destructor [decoration construction / destructor]

Objective-C is finally translated into C language, and of courseconstructor / destructor

The functions with these two attributes will be called when they are in the executable file (or shared library) loadand unloadrespectively , which can be understood as 调用前being executed after the main() function and return. In fact, the constructor will +loadbe executed later, because dyld (dynamic linker) will first notify the objc runtime to load all the classes in it, and each time a class is loaded, it will be called +loadaccordingly all constructorthe ways

__attribute__((constructor)) static void beforeMain() {
    
     
   NSLog(@"before main");
}
__attribute__((destructor)) static void afterMain() {
    
     
   NSLog(@"after main");
}


int main(int argc, const char * argv[]) {
    
     
    @autoreleasepool {
    
    
          NSLog(@"execute main");
      }
  return 0; 
 

Execution result:
debug-objc[23391:1143291] before main
debug-objc[23391:1143291] execute main
debug-objc[23391:1143291] after main

Add the setting priority after the constructor to control the execution order

__attribute__((constructor(101))) static void beforeMain() {
    
     NSLog(@"before main");
}
__attribute__((constructor(100))) static void beforeMain1() {
    
     NSLog(@"before main1");
}
__attribute__((destructor)) static void afterMain() {
    
     NSLog(@"after main");
}

Execution result:
2019-10-12 15:48:24.015908+0800 Food[4561:144694] before main1
2019-10-12 15:48:24.016491+0800 Food[4561:144694] before main
2019-10-12 15: 48:24.017145+0800 Food[4561:144694] execute main

4. overloadable can allow the generation of functions with the same name [modified function]

__attribute__((overloadable)) void testMethod(int age) {
    
    NSLog(@"%@", @(age));};
__attribute__((overloadable)) void testMethod(NSString *name) {
    
    NSLog(@"%@", name);};
__attribute__((overloadable)) void testMethod(BOOL gender) {
    
    NSLog(@"%@", @(gender));};
 
int main(int argc, char * argv[]) {
    
    
    @autoreleasepool {
    
    
        testMethod(18);
        testMethod(@"lxz");
        testMethod(YES);
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

Execution result:
2019-10-12 16:01:04.491366+0800 Food[4724:150619] 18
2019-10-12 16:01:04.491510+0800 Food[4724:150619] lxz
2019-10-12 16:0 1: 04.491632+0800 Food[4724:150619] 1

5. The objc_runtime_name attribute can specify Class or Protocol as another name at compile time [modified class]

__attribute__((objc_runtime_name("TestObject")))
@interface AAA : NSObject
 
@end
 
int main(int argc, char * argv[]) {
    
    
    @autoreleasepool {
    
    
         NSLog(@"--%@",NSStringFromClass([AAA class]));
        
        NSLog(@"----%@",NSClassFromString(@"TestObject"));
  }
}

6. Through the cleanup attribute, it can be assigned to a variable, and a function will be executed before the variable is released [Modify variable]

The execution of the specified function is before dealloc. In the specified function, a formal parameter can be passed in, the parameter is the variable modified by cleanup, and the formal parameter is an address.

static void releaseBefore(NSObject **object) {
    
    
    NSLog(@"AAA-------%@", *object);
}

int main(int argc, char * argv[]) {
    
    
    @autoreleasepool {
    
    
        
        {
    
    
           AAA *object __attribute__((cleanup(releaseBefore)))  = [AAA new];
        }
       
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

Execution result:
2019-10-12 16:20:24.230282+0800 Food[5057:162194] AAA-------<AAA: 0x6000021c81d0>
2019-10-12 16:20:24.230633+0800 Food[5057: 162194] AAA-dealloc

7. Eliminate the unused xxx warning through unused [Modify variable]

If a variable is not used, it will prompt unused xxx, you can use unused to eliminate this warning

int main(int argc, char * argv[]) {
    
    
    @autoreleasepool {
    
    
     
        AAA *object  __attribute__((unused))  = [AAA new];
      
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

Guess you like

Origin blog.csdn.net/zhanglei5415/article/details/129880063