用__Attribute__做点好玩的事情:第一篇

之前写过一篇attribute((constructor))用法探究,当时是在看代码的时候,对它产生了偶遇.而这几天,越发发现这个__attribute__的强大.作为一个iOS开发者,我试着总结了一下这个在我们日常开发中的应用.

从 __Nonull说起

苹果在Xcode6.3中引入了这个特性, 目的在于为Swift混编时,让编译器知道这个Object-C对象是不是可选的.使用方法如下:

-(void)openPath:(NSString * _Nonnull)path;

今天在llvm的文档中,发现了一段这样的描述:


The nonnull attribute indicates that some function parameters must not be null, and can be used in several different ways. It’s original usage (from GCC) is as a function (or Objective-C method) attribute that specifies which parameters of the function are nonnull in a comma-separated list. 

大概意思是:
nonnull这个属性表示函数的参数不能为空,并且这个属性有几种不同的使用方式,最基本的用法就是用来修饰函数(或者OC的方法),使用一个用逗号分隔的参数表来表明函数或者方法的那个哪个参数非空.

还是代码比较明显:

-(void)openFile:(NSString*)file __attribute__((nonnull(1)));

当我们这么使用时候:

 [self openFile:nil];

就会得到这么一个警告:


20160928147504628663285.jpg

几个注意点:

  • nonull的参数从1开始
  • OC的隐含参数self_cmd不计入参数范围

_Nonnull_Nullable在文档中也有说明:

_Nonnull修饰指针类型,表示这个指针类型不会把null当做有意义的参数,用法如下:

int fetch(int * _Nonnull ptr);

_Nullable修饰指针类型,表示这个指针类型可以是null的,用法如下:

int fetch_or_zero(int * _Nullable ptr);

注意:它们只能修饰指针类型的参数.

RAC中的 @onExit

用过RAC的应该对这个关键字不陌生,它实现了,当一个变量作用域结束时,调用指定的block,查看这个宏的定义:

#define onExit \
    rac_keywordify \
    __strong rac_cleanupBlock_t metamacro_concat(rac_exitBlock_, __LINE__) __attribute__((cleanup(rac_executeCleanupBlock), unused)) = ^

这个rac_keywordfiy的定义如下:

#if DEBUG
#define rac_keywordify autoreleasepool {}
#else
#define rac_keywordify try {} @catch (...) {}
#endif

这也是为什么onExit使用的时候,前面需要添加一个@,因为只有这样才能凑成完整的@autoreleasepool或者@try {}.
言归正传,我们关注这个部分:

__attribute__((cleanup(rac_executeCleanupBlock), unused))

先说简单的,unused表示函数或者变量可能不用,防止编译器产生警告.
而这个__attribute__((cleanup(...)))用来修饰变量,当变量的作用域结束的时候,就调用参数.参数是一个函数,当然,也可以是block,RAC里面就是这么干的.用代码来说明:

static void stringCleanUp(__strong NSString **string) {
    NSLog(@"%@", *string);
}

static void cleanupBlock(__strong void(^*block)(void)) {
    (*block)();
};

- (void)viewDidLoad {
    [super viewDidLoad];

    __strong NSString * myname  __attribute__((cleanup(stringCleanUp), unused)) = @"kenny";
    
    __strong void(^block)(void) __attribute__((cleanup(cleanupBlock), unused)) = ^{
        NSLog(@"gonna released");
    };
}

需要注意的是cleanup的参数方法:它的参数是修饰的变量的地址.所以会用到了*block**string,另外:

对于指向objc对象的指针(id *),如果不强制声明__strong默认是__autoreleasing,造成类型不匹配

参考链接:

Common-Variable-Attributes

http://blog.sunnyxx.com/2014/09/15/objc-attribute-cleanup/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • 一、温故而知新 1. 内存不够怎么办 内存简单分配策略的问题地址空间不隔离内存使用效率低程序运行的地址不确定 关于...
    SeanCST阅读 7,774评论 0 27
  • attribute是GNU C特色之一,在iOS用的比较广泛.系统中有许多地方使用到. attribute可以设置...
    youngyunxing阅读 28,368评论 7 66
  • 原文地址:C语言函数调用栈(一)C语言函数调用栈(二) 0 引言 程序的执行过程可看作连续的函数调用。当一个函数执...
    小猪啊呜阅读 4,585评论 1 19
  • 一曲俗人言,两抹闲人泪, 酒肉穿肠过,觥倒知不知? 挽袖湿衣,行云流水, 俯仰之间,仕女石上。 远眺目下,尘起拂光...
    音骊绘阅读 276评论 1 1
  • 2016年元月2日,在这冬日里走在这鹿城的小巷里,在时光飞逝咖啡馆里欣赏着这话剧--《暗恋桃花源》,这场景这人...
    时间yi阅读 758评论 1 1