美文网首页
用__Attribute__做点好玩的事情:第一篇

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

作者: kenny肉桂 | 来源:发表于2016-09-28 17:59 被阅读174次

之前写过一篇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/

相关文章

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

    之前写过一篇attribute((constructor))用法探究,当时是在看代码的时候,对它产生了偶遇.而这几...

  • 小萍子上学记

    好玩的一天 今天做了一件特别好玩的事情,必须做这件事情呢?这就是吴老师让我们做的事情。这个事情非常的好玩好玩的,天...

  • 用套路做好玩的事情

    1人生活在这个世界上,生存需求不仅仅是满足吃喝玩乐,更重要的是有价值需求,所以必须找到一个好玩的有价值的事情干出来...

  • 记一次so的加密与踩的坑

    原理so文件到底还是ELF文件,思路在于用__attribute__((section("{name}")))这个...

  • Tensorflow安装

    # Mac OS X, CPU only: 看到网上 可以用 Python 编程语言做哪些神奇好玩的事情?可...

  • c语言中__attribute__的意义

    GNU C的一大特色就是__attribute__机制。__attribute__可以设置函数属性(Functio...

  • __attribute__

    GNU C的一大特色就是__attribute__机制。__attribute__可以设置函数属性(Functio...

  • SVProgressHUD源码记二:要点学习

    如何表示弃用的API 使用 __attribute__, deprecated 关键字表示已过时的API 单例创建...

  • 好玩的事情

    突然发现一件好玩的事情差不多是在四年前我居然用相同的标题写了一篇相同的文章但是感触完全不一样哈哈

  • 好玩的事情

    昨天妈妈带我去看电视还带我去游乐场,我还吃了冰淇淋,已经很好玩,很好吃呢,这是很有意思的,事情回家的时候...

网友评论

      本文标题:用__Attribute__做点好玩的事情:第一篇

      本文链接:https://www.haomeiwen.com/subject/vufkyttx.html