OC中的SEL与C中的const void *

开头先说明一下,之所以把这二者放在一起比较,是因为今天看到了一个很有趣的写法

- (void)setLk_imageInfo:(LKImageInfo *)imageInfo
{
    objc_setAssociatedObject(self, @selector(setLk_imageInfo:), imageInfo, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

我们都知道,在OC中如果想给分类添加属性@property是不能直接生成对应的settergetter的而且即使手写settergetter也不能使用实例变量,所以只能通过runtime中这种关联的形式来绑定特定对象。
再来看一下objc_setAssociatedObject的定义:

objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,
                         id _Nullable value, objc_AssociationPolicy policy)

可以看到第二个参数key 需要一个 const void *类型的参数作为绑定的key,以往我在使用这个方法的时候都会自己生成一个key,而今天看到的代码中则使用了@selector(setLk_imageInfo:),传入了一个SEL,对此我也做了简单的实验。

先来看一下SEL的定义:

/// An opaque type that represents a method selector.
typedef struct objc_selector *SEL;

可以看到SEL是一个结构体指针,而 const void *是一个无类型指针常量,所以从 SEL -> const void*来赋值是说得通的,但是如果想反过来使用是不可以的。

const void *sel = @selector(beginTimer);
Obj *obj = [Obj new];
[obj performSelector:sel];

最开始对sel的赋值并不会有警告,因为void*本身就是无类型,但是这段代码将无法执行并且报错。

最后,今天也算是学到了一个写关联的时候偷懒的好方法:D。

你可能感兴趣的:(OC中的SEL与C中的const void *)