OC中self.xxx和_xxx访问的区别,深拷贝和浅拷贝的区别

初学iOS时候,发现有的代码通过self.xxx访问,有时通过_xxx访问,一直搞不清楚有什么区别。其实,通过self.xxx是对属性进行访问,本质是调用属性的setter方法,属性的引用计数器会+1;_xxx是直接对成员属性进行访问,是对指针的赋值,引用计数器没发生改变。下面,通过代码来看一下。

定义属性:

@property (nonatomic, copy)NSString *strCopy1;

@property (nonatomic, copy)NSString *strCopy2;

生成个可变字符串str,内容为“123”,分别通过self.strCopy1、_strCopy2进行赋值,通过打印,发现都能够成功赋值;

然后对这个可变字符串str,进行拼接,内容为“123456”;

再打印self.strCopy1和self.strCopy2,咱们这里原意应该是self.strCopy1和self.strCopy2的值不变,依然为“123”,但是,这里打印结果strCopy1正常为“123”,而strCopy2为“123456”。究竟是为什么?

- (void)viewDidLoad {

[super viewDidLoad];

NSMutableString *str = [NSMutableString stringWithFormat:@"123"];

self.strCopy1 = str;

_strCopy2 = str;

NSLog(@"strCopy1:%@ -------- strCopy2:%@",self.strCopy1,self.strCopy2 );

//    打印出来: strCopy1:123 -------- strCopy2:123

[str appendString:@"456"];

NSLog(@"strCopy1:%@ -------- strCopy2:%@",self.strCopy1,self.strCopy2 );

//    打印出来: strCopy1:123 -------- strCopy2:123456

}

因为通过self.strCopy1赋值是调用了编译器默认生成的setter方法,调用了[_strCopy1 copy],copy为内容拷贝,就是深拷贝,_strCopy1已经指向了重新生成的另一块内存了,不是原来_str指向的那一块内存了,所以改变_str原来指向的那块内存里面的字符串内容,不影响_strCopy1指向的内容。

而通过_strCopy2赋值,没有进行内容拷贝(深拷贝),只是进行了指针拷贝(浅拷贝),_strCopy2仍然指向_str原来指向的那块内存。所以改变_str原来指向的那块内存的字符串内容,会直接影响_strCopy2的内容。

其实,copy和retain的区别就是深拷贝和浅拷贝的原因。也是为什么修饰NSString的是copy,而不是其他。

时间: 2025-01-03 22:21:15

OC中self.xxx和_xxx访问的区别,深拷贝和浅拷贝的区别的相关文章

Python中深拷贝与浅拷贝的区别

Python中深拷贝与浅拷贝的区别: 原创 2017年04月20日 16:58:35 标签: python / python两种拷贝 / 深拷贝浅拷贝 / 拷贝区别 1661 定义: 在Python中对象的赋值其实就是对象的引用.当创建一个对象,把它赋值给另一个变量的时候,python并没有拷贝这个对象,只是拷贝了这个对象的引用而已. 浅拷贝:拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已.也就是,把对象复制一遍,但是该对象中引用的其他对象我不复制 深拷贝:外围和内部元素都进行了拷贝

JS中深拷贝与浅拷贝的区别,实现深拷贝的几种方法

JS中深拷贝与浅拷贝的区别,实现深拷贝的几种方法 如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力. 此篇文章中也会简单阐述到栈堆,基本数据类型与引用数据类型,因为这些概念能更好的让你理解深拷贝与浅拷贝. 我们来举个浅拷贝例子: let a=[0,1,2,3,4], b=a; console.log(a===b); a[0]=1; console.log(a,b); 嗯?明明b复

js 中引用类型 的深拷贝 和 浅拷贝的区别

一.曾经在读JQ源码的时候,对深拷贝算是有了一点的理解.我们在项目中是不是经常会遇到这样的问题呢? 后台返回一个数组对象(引用类型).次数在页面渲染中需要对部分数据进行处理 比如:银行卡62345092534 (这么长) 但在页面显示的时候, 只显示中国银行(3118)但是传给后台的时候.又要传623445242整个号码,我们也许会把var oldData = res.data; 但是我们发现两个数据都变了? 这是为什么呢? 其实就是一个深浅拷贝的问题. 二.浅拷贝 比如数组,对象,这样的引用类

iOS中self.xxx 和 _xxx 下划线的区别

property (nonatomic,copy) NSString *propertyName; self.propertyName 是对属性的拜访: _propertyName 是对部分变量的拜访. 其1.@property的声明中,编译器正在天生g] @property (nonatomic,copy) NSString *propertyName; self.propertyName 是对属性的访问: _propertyName 是对局部变量的访问. 其一.@property的声明中,编

Python中复制、深拷贝和浅拷贝的区别

深拷贝定义(deepcopy) 在Python中,由于一切皆对象,所以任何变量都可以被引用,也即可以被赋值给任何变量.但是在Python中,给变量赋值,是区分的,一般情况下,Python中的变量赋值都是浅拷贝,如果需要使用深拷贝,需要特别指定. 深拷贝是对原对象的"复制以及粘贴",其实就是在内存中重新开辟了一个新的内存空间来存放这一份数据,两个变量其实是两个不一样的变量,仅仅是数据值相同而已,对两个变量的操作不会相互影响. 浅拷贝(copy) 在Python中进行数据的浅拷贝时,如果此

iOS中的 深拷贝和浅拷贝

#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { // 一: copy 与 retain 的区别 // 谁才有引用计数的概念: // 1. 堆区空间才有引用计数概念. // 2. 堆区的对象才会有引用计数. //%ld: - 1 %lu:18446744073709551615 //retain:始终是浅拷贝.引用计数每次加一. //返回对象是否可变与被复制的对象保持一致. //copy:对于

C#中的深拷贝与浅拷贝

1.基本的概念: 首先我们应该了解一下什么叫深拷贝与浅拷贝(Deep Copy and Shallow Copy). a.浅拷贝(Shallow Copy影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用. b.深拷贝(Deep Copy 深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.完全产生新对象. 深拷贝与浅拷贝不同的是对于引用拷贝的处理,深拷贝将会在新对象中创建和原是对象中对应值类型的字段并且赋值.浅拷贝不会创建新引用类型,会返回相同的类 型引用.深拷贝会重新创建新

探究JS中对象的深拷贝和浅拷贝

深拷贝和浅拷贝的区别 在讲深拷贝和浅拷贝的区别之前,回想一下我们平时拷贝一个对象时是怎么操作的?是不是像这样? var testObj1 = {a: 1, b:2}, testObj2=testObj1; testObj1.a = 7; console.log(testObj1); //{a: 7, b:2} console.log(testObj2); //{a: 7, b:2} 发现问题了吗?当testObj1变化时,testObj2相应的属性跟着变化了.这就是属于浅拷贝了,而所谓的深拷贝就

Python中list的复制及深拷贝与浅拷贝探究

在Python中,经常要对一个list进行复制.对于复制,自然的就有深拷贝与浅拷贝问题.深拷贝与浅拷贝的区别在于,当从原本的list复制出新的list之后,修改其中的任意一个是否会对另一个造成影响,即这两个list在内存中是否储存在同一个区域,这也是区分深拷贝与浅拷贝的重要依据.接下来我们就针对Python中list复制的几种方法,来探究一下其是属于深拷贝还是浅拷贝.弄清楚这个问题,有助于我们在编程中规避错误,减少不必要的调试时间. 一.非拷贝方法--直接赋值 如果用=直接赋值,是非拷贝方法.这