美文网首页
iOS:self.xx vs self->_xx vs _xx

iOS:self.xx vs self->_xx vs _xx

作者: 码农二哥 | 来源:发表于2022-05-11 11:39 被阅读0次

    基本理解

    • self.xx 是对类的属性访问,会调用getter、setter方法;
    • _xx 是直接对实例变量的操作;
    • _xx 类似于 self->_xx(类外肯定没法用 _xx,但 self->_xx 还是有想象空间的)。
    • 所有被声明为属性的成员,在iOS5 之前需要使用编译器指令@synthesize 来告诉编译器帮助生成属性的getter,setter方法。之后这个指令可以不用人为指定了,默认情况下编译器会帮我们生成。
    • 编译器在生成getter,setter方法时是有优先级的,它首先查找当前的类中用户是否已定义属性的getter,setter方法,如果有,则编译器会跳过,不会再生成,使用用户定义的方法。

    深层理解

    • 用 _xx 访问时,在编译期程序就已经知道它的内存地址了,运行时是直接通过偏移量这种硬编码方式访问变量的内存地址;
      (1) 使用 _ 是获取不到父类的属性,因为它只是对局部变量的访问。
      (2) 另外,直接访问实例变量,将不会触发键值观测(KVO)的通知
    • 用 self.xx 访问时,是在运行时通过消息机制动态的访问变量的。
      (1) 从内存管理的视角看,根据属性修饰符的不同,setter方法并不仅仅是将传入的参数直接赋值给实例变量,而是经过了一些简单的操作(比如引用计数、原子性等)

    实战经验

    • 尽管 _xx 的性能更好,如果不是必须,建议使用 self.xx,原因有(1)容易在 block 中造成循环引用 (2)直接访问实例变量,将不会触发键值观测(KVO)的通知。这样做是否会产生问题,还取决于具体的对象行为 (3)团队编码规范简单、统一。
    • 必须使用 _xx 的场景,比如重写 getter 或者 setter 时,内部不能再使用 self.xx 了

    延伸思考

    • synthesize、dynamic 的用法?
    • 下面输出 _view1 的内容时有值吗?为什么?
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        
        _view1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"%@", self.view1);
        });
    }
    
    • getter、setter 一般是如何实现的?
    • 原子性是什么意思?
    • 引用计数的原理?

    相关文章

      网友评论

          本文标题:iOS:self.xx vs self->_xx vs _xx

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