美文网首页iOS程序猿iOS Developer
在Objective-C中self关键字到底是什么

在Objective-C中self关键字到底是什么

作者: Little_Mango | 来源:发表于2017-02-24 18:52 被阅读806次

在实例方法中Self指代本类的实例对象。
在类方法中Self指代类对象

上面就是结论,注意一下类的实例对象和类对象(元类的实例对象)的区别。

举个例子来证明

#import "MGExample.h"

@implementation MGExample

- (instancetype)initWithDict:(NSDictionary *)dict
{
    if (self = [super init]) {
        [self setValuesForKeysWithDictionary:dict];
    }
    return self;
}
+ (instancetype)heroWithDict:(NSDictionary *)dict
{
    return [[self alloc] initWithDict:dict];
}
@end

上面两个方法一个是实例方法,一个是类方法,在clang -rewrite-objc MGExample.m之后,代码如下:

static instancetype _I_ MGExample_initWithDict_(MGExample * self, SEL _cmd, NSDictionary *dict) {
    if (self = ((MGExample *(*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("MGExample"))}, sel_registerName("init"))) {
        ((void (*)(id, SEL, NSDictionary<NSString *,id> *))(void *)objc_msgSend)((id)self, sel_registerName("setValuesForKeysWithDictionary:"), (NSDictionary<NSString *,id> *)dict);
    }
    return self;
}

static instancetype _C_ MGExample_heroWithDict_(Class self, SEL _cmd, NSDictionary *dict) {
    return ((id (*)(id, SEL, NSDictionary *))(void *)objc_msgSend)((id)((id (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("alloc")), sel_registerName("initWithDict:"), (NSDictionary *)dict);
}

从两个方法的第一个传入参数的类型可以很明显得出最上面的结论。


补充一下,类对象的生命周期是从该类载入程序的时候开始,直到程序结束,类对象的生命周期才结束,所以一般不要给类对象设置关联对象,因为这样做之后该关联对象的生命周期会变得非常长,超乎你的想象。以UIGestureRecongzier分类为例子:

//以下为错误代码
+ (instancetype)bp_recongizerWithActionBlock:(BPGestureBlock)block {
    //self指类对象。
    objc_setAssociatedObject(self, &blockKey, block, OBJC_ASSOCIATION_COPY);
    return [[self alloc] initWithTarget:self action:@selector(bp_block:)];
}

+ (void)bp_block:(UIGestureRecognizer *)gest {
    BPGestureBlock block = objc_getAssociatedObject(self, &blockKey);
    if (block) {
        block(gest);
    }
}

如果像上面那样写,则会造成block被类对象持有,导致资源得不到及时的释放,或者说不像我们期待的那样随着UIGestureRecognizer实例对象的释放而释放,因为关联block的对象是类对象而不是实例对象。正确的写法中的一种可以像下面的示例:

+ (instancetype)bp_recognizerWithBlock:(BPGestureBlock)block {
    return [[self alloc] initWithBlock:block];
}

- (instancetype)initWithBlock:(BPGestureBlock)block {
    self = [self init];
    if (self) {
        objc_setAssociatedObject(self, &blockKey, block, OBJC_ASSOCIATION_COPY);
        [self addTarget:self action:@selector(p_handleBlock)];
    }
    return self;
}

- (void)p_handleBlock {
    BPGestureBlock block = objc_getAssociatedObject(self, &blockKey);
    if (block) {
        block(self);
    }
}

相关文章

  • 在Objective-C中self关键字到底是什么

    在实例方法中Self指代本类的实例对象。在类方法中Self指代类对象 上面就是结论,注意一下类的实例对象和类对象(...

  • Objective-C 中Self 和 Super 详解

    在 Objective-C 中的类实现中经常看到这两个关键字 ”self” 和 ”super”,以以前 oop 语...

  • Self关键字

    Self关键字代表什么 在实例方法中Self指代本类的实例对象。在类方法中Self指代类对象 为什么可以在方法中使...

  • Objective-C 中Self 和 Super 详解

    Objective-C中Self和Super详解本文要介绍的内容,在Objective-C中的类实现中经常看到这两...

  • [OC]self与super调用本质分析

    一、self 基本说明 在日常开发中,我们经常使用到self关键字,比如,访问属性,调用实例方法等。那么self到...

  • Swift中self和Self

    是什么 相信大家都知道self这个关键字的具体作用,它跟OC里的self基本一样。但是对于Self来说...(WT...

  • scala中的self =>

    在scala的一些开源项目的源码中总是能看到类似self =>关键字,那这到底代表什么呢?在此,记录一下,仅作为笔...

  • iOS中self与super

    一.self关键字 OC语言中的self,就相当于C++、Java中的this指针 1.类方法中的self...

  • 题目小记

    1. Objective-C 对象是什么?Class 是什么?id 又是什么? 在 Objective-C 中,每...

  • Swift3.0 Self和self的区别

    相信大家都知道self关键字的作用, 但你知道Swift还有个Self关键字吗?Self关键字只能用在类里, 作为...

网友评论

    本文标题:在Objective-C中self关键字到底是什么

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