OC顶用指针修改对象属性容易进的误区,看你中过枪没有
对于初学者朋友,在OC指针指针修改对象属性掌握起来一般问题不大的,但是要再来几个"函数"和你"折腾"呢?哈哈!看看你又没有中过枪吧!看下面一段代码:
void test1(int newAge,double newHeight); void test2(Person *newP); void test3(Person *newP); void test4(Person *newP); int main(){ Person *p= [Person new]; p->_age = 10; p->_height = 1.2f; test1(p->_age, p->_height); [p print]; test2(p); [p print]; test3(p); [p print]; test4(p); [p print]; return 0; } void test1(int newAge,double newHeight) { newAge = 30; newHeight = 1.4; } void test2(Person *newP) { newP->_age = 20; newP->_height = 3.3; } void test3(Person *newP) { Person *p2 = [Person new]; p2->_height = 4.4; p2->_age = 50; newP = p2; newP ->_age = 60; } void test4(Person *newP) { Person *p2 = newP; p2->_age = 18; p2->_height = 5.1; newP->_age =25; }
自信的朋友可以默默的写下你们的答案,我们来对下答案吧
age = 10,height = 1.200000
age = 20,height = 3.300000
age = 20,height = 3.300000
age = 25,height = 5.100000
原理:看一下原理之前,我们先要明白一件事:当创建一个对象后,系统会为我们做3件事情:1.会在堆中开辟一块存储空间(堆有个特性,就是不会自动释放)2.会初始化对象属性为零 3.会返回一个地址给对象(把每个属性看出一个元素的话,那么第0个元素是系统生成的地址"isa",这也就是对象的地址)
test1:在栈中开辟一块存储空间,把10和1.2f赋值给newAge和newHeight,函数调用结束后test1函数释放
test2:把p赋值给Person *newP,那么*newP就等于p了,相当于通过newP访问p指向的存储空间,函数调用结束后test2函数释放
test3:(这一点我觉得比较复杂,也是容易进入误区的地方) 把p的值赋值给test3中的newP,newP此时指向先开辟的[Person new],随后test3中有个新指针p2指向堆中新开辟的[Person new],之后又把p2的值赋值给newP(也就算说覆盖了原来的地址),那么newP就是指向后开辟的[Person new],所以再通过newP访问的age是后开辟的[Person new]中的age,不会影响先开辟的[Person new]中的属性,但此时上面已经调用了test2了,所以属性结果和上面相同.
test4:相当于直接把newP赋值了p2,无论通过p2还是newP来修改对象属性都是一回事.
如有还是想不清楚的话,自己画个图理解可能比较容易,也可以和我进一步讨论,一起进步!
好了,今天就到这了,如有不正之处,还望各位看官之处,感激不尽!
----奈文摩尔