------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
1、简单的例子
我们创建了一个Person类,然后可以打印一下的引用计数值:1
当我们调用retain方法的时候,引用计数就会+1,当我们调用release方法的时候引用计数会-1
一旦系统发现引用计数为0的时候,就会销毁这个对象,调用dealloc方法
2、set方法来控制引用计数
这个例子简单吧,没什么问题的,现在我们把问题复杂化
我们定义了两条狗,然后将这两条狗通过setDog方法设置到p1对象上,同时将第一条狗设置到p2对象上,这时候我们打印一下第一条狗的引用计数,发现他的引用计数是1,原因很简单,这个1是在alloc时候有的,但是现在是有问题的,因为第一条狗被p1和p2引用者,按照正常情况,第一条狗的引用计数为3的。所以这时候我们就需要修改一下Person类中setDog方法了
我们需要手动的增加dog的引用计数,这样就正常了。
现在又有一个问题了,上面p1对象设置了第二条狗
按照上面的setDog方法,我们又发现一个问题,现在p1引用的狗是第二条狗了,不是第一条,那么这时候按照正常情况第一条狗的引用计数-1,因为他已经不再被p1引用了。所以setDog方法还得修改:
这时候我们就在赋值之前,对_dog调用一次release方法,这样就解决了上面的那个问题。
但是现在还有一个问题:
在执行release代码之后,dog1的引用计数为1,这是继续调用setDog方法:
这时候_dog是dog1,继续调用release方法,执行完之后,引用继续为0了,对象被释放了,但是这时候dog参数的值还是dog1,那么在执行retain方法就会报错了,这个原因很简单,就是我们两次调用了setDog方法,将dog1设置了两次。中间调用一次release方法。所以解决这样的问题,我们在修改一下setDog方法:
我只需要判断一下,之前的属性值和当前需要设置的值是否相同。这种方式就是没有问题了,所以我们以后在写set方法的时候,这就是模板了。
3、销毁方法dealloc控制引用计数
现在假如p1被销毁了,那么对于dog1来说引用计数应该-1的,所以需要在Person类中的dealloc方法中修改一下:
4、初始化方法控制引用计数
现在还有一种情况,如果我们使用初始化方法来设置Dog属性值:我们这里的处理和setDog方法的处理方式一样,但是这里不需要做一次判断了,因为初始化方法只会调用一次。所以不会出现setDog的第三种情况。