__attribute__ 高级运用
2018-08-22 本文已影响13人
洲洲哥
__attribute__((cleanup(...)))
,用于修饰一个变量(对象),在它的作用域结束时可以自动执行一个指定的方法
例如:
基本用法
1:对于Class对象
// 指定一个cleanup方法,注意入参是所修饰变量的地址,类型要一样
// 对于指向objc对象的指针(id *),如果不强制声明__strong默认是__autoreleasing,造成类型不匹配
// 加了个`unused`的attribute用来消除`unused variable`的warning
static void ZZGCleanUp(__strong ZZG **zzg) {
NSLog(@"%@",*zzg);
}
{
// 调用
__strong Sark *sark __attribute__((cleanup(ZZGCleanUp),unused)) = [ZZG new];
}
// 当运行到这个作用域结束时,自动调用ZZGCleanUp
2:对于NSString对象
static void stringCleanUp(__strong NSString **string) {
NSLog(@"%@", *string);
}
{
__strong NSString *string __attribute__((cleanup(stringCleanUp))) = @"ZZG";
} // 当运行到这个作用域结束时,自动调用stringCleanUp
高级用法
1:既然__attribute__((cleanup(...)))
可以用来修饰变量,block
当然也是其中之一
一块搞一个block
// void(^block)(void)的指针是void(^*block)(void)
static void blockCleanUp(__strong void(^*block)(void)) {
(*block)();
}
于是在一个作用域里声明一个block:
{
__strong void(^block)(void) __attribute__((cleanup(blockCleanUp), unused)) = ^{
NSLog(@"block.......");
};
} // 这里输出"block......."
2:写一个实例如下
2.1:创建一个AttributeLock
类
在.h
中如下定义
typedef void (^zzg_cleanupBlock_t)(void);
static inline void zzg_executeCleanupBlock (__strong zzg_cleanupBlock_t *block) {
(*block)();
}
// 该对象在代码段释放前调用的函数
#define attributeExit\
__strong void(^block)(void) __attribute__ ((cleanup(zzg_executeCleanupBlock),unused)) = ^
#import <Foundation/Foundation.h>
@interface AttributeLock : NSObject
-(void)start;
-(void)stop;
@end
在.m
如如下
#import "AttributeLock.h"
@implementation AttributeLock
1. -(void)dealloc {
NSLog(@"---dealloc");
}
-(void)start {
NSLog(@">>>>>>>start");
}
-(void)stop {
NSLog(@"<<<<<<stop");
}
@end
2.2:调用如下
AttributeLock * loc = [[AttributeLock alloc] init];
[loc start];
// *** 该方法可以放在任何位置
attributeExit {
NSLog(@"===========exit");
};
[loc stop];
2.3:打印如下
2018-08-22 20:16:18.524553+0800 POSPay[83808:9075309] >>>>>>>start
2018-08-22 20:16:18.524708+0800 POSPay[83808:9075309] <<<<<<stop
2018-08-22 20:16:18.524923+0800 POSPay[83808:9075309] ===========exit
2018-08-22 20:16:18.525214+0800 POSPay[83808:9075309] ---dealloc
可以看出在dealloc之前调用该方法
总结ps:
1* 作用域结束时可以自动执行一个指定的方法
2* 指定一个cleanup方法,要注意传入的参数修饰变量的地址,并且类型要一样。并且对于指向Objc对象的指针(id *),如果不强制声明__strong 默认是__autoreleasing,造成类型不匹配
3* 只有在作用域结束时会自动调用cleanup中的方法
4* 如果一个作用域内有若干个cleanup的变量,他们的调用顺序是先入后出
的栈式顺序。而且,cleanup是优先于这个对象的dealloc调用
有些地方说的不到位,还请各位看官指正。。。
- 如有问题可添加QQ群:234812704
- 欢迎各位一块学习,提高逼格!
- 也可以添加洲洲哥的微信公众号
可以来微信公众号(洲洲哥)后台给我们留言。 快来扫码关注我们吧!
公众号二维码