美文网首页
实例变量和属性

实例变量和属性

作者: 远辰jt | 来源:发表于2018-06-02 00:07 被阅读9次

实例变量和属性是两个不同的概念, 属性是iOS5之后新增的概念,属性的正常使用依附于实例变量
1,实例变量
1.1,定义形式

{
    float privateVariable1;
    NSString *privateVariable2;
}

1.2 访问权限类型

访问权限共四种:
 @package    在包内是可以访问的
 @public     公开的,不管在哪里都可以访问
 @protected   受保护的, 能在当前类及其子类中访问,  默认情况下如果实例变量没有声明访问类型就是这种
 @private     私有的, 只有在当前类中才能访问 

以上情况是默认实例变量定义在.h 文件中的, 如果定义在.m文件中, 无论修饰符是什么外部都不能访问,相当于private

1.3内存管理策略

共四中__strong、__weak、__unsafe_unretained和__autoreleasing。

__strong修饰符
__strong修饰符是id类型和对象类型默认的所有权修饰符。
__strong修饰符表示对对象的“强引用”。持有强引用的变量在超出其作用域时被废弃,随着强引用的失效,引用的对象会随之释放,引用计数减1。

__weak修饰符
__strong修饰符修饰的变量表示强引用,意味着只要还有一个强引用存在,对象就不可能释放,但是有一个问题就是两个对象互相强引用,就会造成循环引用,__weak表示的是弱引用, 弱引用对对象的生命周期不会产生影响,并且当对象销毁时,__weak修饰的变量会自动设置为nil。所以可以用__weak修饰的变量是否为nil来判断对象是否已经被销毁。

__unsafe_unretained
顾名思义,它是不安全的, 和__weak相似但是有区别,相同点就是不会对对象的生命周期产生影响, 不会影响对象的引用计数,但是它是不安全的,当对象被销毁时,它不会自动设置为nil, 还是原来对象的地址。如果这个时候访问变量就会报野指针错误,所以使用的时候一定要确保对象存在。

__autoreleasing
用__autoreleasing修饰的变量的作用等同于ARC无效时调用autorelease方法,都是起到延时释放的作用。ARC有效时,用@autoreleasepool块替代NSAutoreleasePool类,用附有__autoreleasing修饰符的变量代替autorelease方法

1.4访问 和赋值
对于在当前类或者其子类内部, 有两种方式拿到实例变量: 可以直接使用实例变量名 或者 self->实例变量名进行取值和赋值

variable1 = @"asdfasdf";
self->variable2 = 123.1;

对于在外部访问实例变量时,只能使用对象->实例变量名

    JTNewClassTest *asdf = [JTNewClassTest new];
    asdf->variable1 = @"新赋值";
    NSLog(@"%@",asdf->variable1);

2 属性
2.1,定义形式

@property (可变参数列表) BOOL property1;
可变参数列表中有四种类型的参数
* 原子属性  有atomic和nonatomic两种类型,其中默认是atomic类型,原子的 线程安全的
* 读写属性  默认是可读写的   当然可以readonly  和 readwrite 两种,默认是readwrite可读写的
* setter  或者 getter方法名, 默认情况下 如果没有指定,set方法名就是set属性名,  get方法就是get属性名,  当然可以另外指定方法名
* 内存管理策略:
  ** strong, weak, assign, retain, copy,unsafe_unretained
其中strong、retain和copy对应__strong,修饰对象类型,表示强引用。
weak对应__weak 表示弱引用。assign和unsafe_unretained都对应__unsafe_unretained, 其中assign修饰基本数据类型,unsafe_unretained一般修饰对象类型,但是不安全的,使用的时候要确保对象存在。

用@property声明的属性默认情况下回自动生成名为_属性名的实例变量,和setter和getter方法
2.2 不要自己实现属性的setter和getter方法,因为 系统检测到你实现了setget方法就不会自动生成实例变量,,所以如果想自己实现就实现两个方法再添加一个实例变量

@property (nonatomic,assign)BOOL property1;
- (void)setProperty1:(BOOL)property1{
    _property1 = property1;
}

- (BOOL)property1{
    return _property1;
}
这种情况下 编译会报错,提示找不到实例变量_property1

2.3@synthesize 的作用

synthesize是合成的意思属性绑定 指定属性对应的实例变量的名字

@property 和 @synthesize在Xcode4.4以前一直都是配合着使用,在4.4以后,@property得到了增强,一行代码编译器就会自动帮我们生成setter和 getter方法的声明和实现,同时在.m文件中声明一个和属性名一样并且在最前面带有下划线的成员变量 (private)

@synthesize 属性名;                会生成和属性同名的实例变量,当然可以指定实例变量的名字。
@synthesize 属性名 = 实例变量名;    指定属性和对应的实例变量名 

3,属性和实例变量的区别
访问属性的本质是调用属性的set和get方法。访问实例变量的本质是计算偏移量然后直接在内存中读取数据。所以存取方法有区别导致效率也有区别
3.1 实例变量访问效率要比属性高。
3.2 实例变量不能触发KVO, 属性能触发。
3.3 属性比较方便调试。

那么我们在开发中到底是用属性还是用实例变量呢? 这个分情况,在初始化和析构方法中最好用实例变量,其他都可以使用属性来实现访问了,除了在属性的set和get方法中(不然会循环调用)
参考文章 https://www.jianshu.com/p/74d669592349

相关文章

  • Python实例变量和类变量

    Python实例变量和类变量 类变量(类属性): 类变量属于类所有,所有实例共享一个变量 实例变量(实例属性) 实...

  • 2020-04-05 KVC

    课程引入:成员变量、实例变量、属性,区别是什么?---分类不能添加实例变量 成员变量 -- 实例变量 -- 属性 ...

  • 实例变量和属性

    实例变量和属性是两个不同的概念, 属性是iOS5之后新增的概念,属性的正常使用依附于实例变量1,实例变量1.1,定...

  • swift面向对象基础<二>

    存储属性和计算属性 今天讨论实例存储属性与实例变量,结构体常量与实例属性,定义计算属性,setter方法,属性观察...

  • 实例变量和属性变量的比较

    导言 实例变量和属性变量的使用 当在对象之外使用实例变量时,我们通过属性来访问。但当我们在对象之内使用实例变量时,...

  • OC之属性与实例变量

    目录 属性和实例变量的关系关于强引用、弱引用关于Copy 与 mutableCopy 属性和实例变量的关系 很多时...

  • 52个有效方法阅读笔记(二)

    1.属性和实例变量:属性(property)和实例变量其实就是对象保存数据的一种方法.a. 属性会自动生成获取方法...

  • iOS之成员变量、实例变量、属性

    作为iOS开发,会经常听到成员变量、实例变量和属性;那他们有什么区别吗? 实例变量 实例变量:class类进行实例...

  • 类中常量和静态变量的区别

    结论 静态变量和常量属于类属性。其他变量属于对象属性或者实例属性。 实例的属性才可以用 $obj->c 这种方式访...

  • 属性(property)和实例变量

    本文主要是解决什么属性和实例变量的区别,什么时候使用属性和实例变量,@synthesize的作用又是什么? 首先我...

网友评论

      本文标题:实例变量和属性

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