OC顶用指针修改对象属性容易进的误区,看你中过枪没有

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:在栈中开辟一块存储空间,101.2f赋值给newAgenewHeight,函数调用结束后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来修改对象属性都是一回事.

        如有还是想不清楚的话,自己画个图理解可能比较容易,也可以和我进一步讨论,一起进步!

        好了,今天就到这了,如有不正之处,还望各位看官之处,感激不尽!

                                                                                                                                                                      ----奈文摩尔