iOS 属性 @property

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS 属性 @property相关的知识,希望对你有一定的参考价值。

参考技术A

声明 @property 时,注意关键词及字符间的空格。

@property 的本质其实是: ivar (实例变量) + getter + setter ;

接下来逐个介绍一下,每个关键词的作用:

指定获取属性对象的名字为 getterName ,如果你没有使用 getter 指定 getterName ,系统默认直接使用 propertyName 访问即可。通常来说,只有所指属性需要我们指定 isPropertyName 对应的 Bool 值时,才使用指定 getterName ,一般直接用 PropertyName 即可。 setter=setterName: 则是用来指定设置属性所使用的的 setter 方法,即设置属性值时使用 setterName: 方法,此处 setterName 是一个方法名,因此要以":"结尾,具体示例如下:

表示强引用关系,即修饰对象的引用计数会+1,通常用来修饰对象类型,可变集合及可变字符串类型。当对象引用计数为0,即不被任何对象持有,且此对象不再显示在列表中时,对象就会从内存中释放。

对象不进行 retain 操作,即不改变对象引用计数。通常用来修饰基本数据类型( NSInteger, CGFloat, Bool, NSTimeInterval 等),内存在栈上由系统自动回收。
assign 也可以用来修饰 NSObject 类型对象,因为 assign 不会改变修饰对象的引用计数,所以当修饰对象的引用计数为0,对象销毁的时候,对象指针不会被自动清空。而此时对象指针指向的地址已被销毁,这时再访问该属性会产生野指针错误: EXC_BAD_ACCESS ,因此 assign 通常用来修饰基本数据类型。

当调用修饰对象的 setter 方法时,会建立一个引用计数为 1 的新对象,即对象会在内存里拷贝一份副本,两个指针指向不同的内存地址。一般用于修饰字符串( NSString )和集合类( NSArray , NSDictionary )的不可变变量, Block 也是用 copy 修饰。
针对 copy ,这里又牵涉到了深 copy 和浅 copy 的问题,这里做一下简单介绍,后续会有文章专门探讨这个问题:

注意:当使用 copy 修饰的属性赋值时, copy 出来的是一份不可变对象。因此当对象是一个可变对象时,切记不要使用 copy 进行修饰。如果这时使用 copy 修饰,当使用 copy 出来的对象调用可变对象所特有的方法时,会因为找不到对应的方法而 Crash 。

表示弱引用关系,修饰对象的引用计数不会增加,当修饰对象被销毁的时候,对象指针会自动置为 nil ,防止出现野指针。 weak 也用来修饰 delegate ,避免循环引用。另外 weak 只能用来修饰对象类型,且是在 ARC 下新引入的修饰词, MRC 下相当于使用 assign 。

weak 的底层实现是基于 Runtime 底层维护的 SideTables 的 hash 数组,里面存储的是一个 SideTable 的数据结构:

这里重点说一下 weak_entry_t 定长数组 动态数组 的切换,首先会将原来定长数组中的内容转移到动态数组中,然后再在动态数组中插入新的元素。
而对于动态数组中元素个数大于或等于总空间的 3/4 时,会对动态数组进行总空间 * 2 的扩容

每次动态数组扩容,都会将原先数组中的内容重新插入到新的数组中。

备注: 此处省略了 weak 底层实现的很多细节,具体详细实现,后续会单独发文介绍。

设置属性函数 reallySetProperty(...) 的原子性非原子性实现如下:

获取属性函数 objc_getProperty(...) 的内部实现如下:

由此可见,对属性对象的加锁操作仅限于对象的 getter/setter 操作,如果是 getter/setter 以外的操作,该加锁并没有意义。因此 atomic 的原子性,仅能保障对象的 getter/setter 的线程安全,并不能保障多线程下对对象的其他操作安全。如一个线程在 getter/setter 操作,另一个线程进行 release 操作,可能会导致 crash 。此种场景的线程安全,还需要由开发者自己进行处理。

那如何给 Category 实现类似实例变量功能呢?简单列举两种方式,此处暂时不做具体详解,后续会有文章单独介绍:

根据苹果官方文档的建议,如果捕获的引用永远不会变为 nil ,我们应该使用 unowned ,否则应该使用 weak 。

@property 延展相关的技术点有很多,如: copy 相关的 NSCopying 协议, weak 底层详细的实现原理,如何保障对象的多线程安全。还有很多技术点跟 Runtime 、Runloop 有关,后续文章会陆续介绍。
知识点完整说下来就是一整套系统的协同运转,各个环节紧密相扣,最终才成为我们现在看到的样子。本文及以后的文章都会尽可能的收缩一下单篇文章探讨的范围,以期能够让话题更加紧密。

Java IO流-Properties

2017-11-05 21:37:50

  • Properties

Properties:Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。

        Properties是一个属性集合类,是一个可以和IO流相结合的使用的集合类。

        Properties类 可以保存在流中或者从流中加载,是Hashtable的子类,也就是Map的子类。

*构造方法

*常用方法

~ Properties作为Map集合的使用

public class Main {
    public static void main(String[] args) {
        //没有泛型,不是泛型类
        Properties prop = new Properties();

        //添加元素
        prop.put("1","hello");
        prop.put("2","world");
        prop.put("3","!");

        //遍历集合
        Set<Object> set = prop.keySet();
        for(Object k:set){
            Object val = prop.get(k);
            System.out.println(k+"---"+val);
        }
    }
}

 ~ Properties的特殊功能

  1. public Object setProperty(String key,String value)
  2. public String getProperty(String key)
  3. public Set<String> stringPropertyNames()
public class Main {
    public static void main(String[] args) {
        //没有泛型,不是泛型类
        Properties prop = new Properties();

        //添加元素
        prop.setProperty("1","hello");
        prop.setProperty("2","world");
        prop.setProperty("3","!");

        //遍历集合
        Set<String> set = prop.stringPropertyNames();
        for(String k:set){
            String val = prop.getProperty(k);
            System.out.println(k+"---"+val);
        }
    }
}

~ Properties与IO流的结合

  1. public void load(Reader reader):把文件中的数据读取到Properties集合中,文件中的数据必须是键值对形式的。
  2. public void store(Writer writer,String comments):把集合中的数据存储到文件中。
        //没有泛型,不是泛型类
        Properties prop = new Properties();

        //添加元素
        prop.setProperty("1","hello");
        prop.setProperty("2","world");
        prop.setProperty("3","!");

        Writer w = new FileWriter("E:/test.txt");
        prop.store(w,"helloworld");
#helloworld
#Sun Nov 05 22:06:16 CST 2017
1=hello
2=world
3=\\!
        Properties prop = new Properties();
        Reader r = new FileReader("E:/test.txt");
        prop.load(r);
        r.close();

 

 

 

 

以上是关于iOS 属性 @property的主要内容,如果未能解决你的问题,请参考以下文章

面向对象-特性property

Python面向对象 | 类属性

特性(property)

property特性

python-类与对象 如何创建可管理的对象属性 (图文并茂)

python-类与对象 如何创建可管理的对象属性 (图文并茂)