zoukankan      html  css  js  c++  java
  • Objective-C 再谈OC指针,对比C++/Java/Swift

    1.Objective-C的指针

    OC一直是人感觉比较变态的一门语言,为什么呢?因为它的每个变量都是指针型,多的都几乎让人忘了那个*的存在了。

    比如我定义了一个Student的Class,new了stu1和stu2,并把stu2=stu1,那当两者任何一个进行修改时,两个变量的内容都会修改。

        Student *stu1=[[Student alloc]init];
        stu1.name=@"stu1";
        Student *stu2=stu1;
        stu2.name=@"stu2";
        NSLog(@"STU1:%@----STU2:%@",stu1.name,stu2.name);//输出两个都是stu2
    

    在C/C++语言里,不习惯用指针作变量的情况下,当然两者是不一样的,实际上“=”号是做了一份拷贝。

        Student stu1;
        stu1.name="stu1";
        Student stu2=stu1;
        stu2.name="stu2";
        cout<<"stu1:"<<stu1.name<<" stu2:"<<stu2.name<<endl;//输出前者stu1,后者stu2
    

    但是上面的情况创建的是C/C++语言里所谓的栈对象,但栈的大小很有限

    在创建堆对象(指针对象)的情况下,就和OC十分相似了

        Student *stu1= new Student();
        stu1->name="stu1";
        
        Student *stu2=stu1;
        stu2->name="stu2";
        cout<<"stu1:"<<stu1->name<<" stu2:"<<stu2->name<<endl;//输出两个都是stu2
    

     在Java里面,虽然变量的创建前面没有*,但其实默认生成的也是堆对象,对象给变量赋值只是一个引用。

     在Swift中,通过下面的=赋值,和Java中一样,stu2是stu1的引用

    import Foundation
    
    var stu1=Student(name: "shen")
    var stu2=stu1
    print("stu1:(stu1)---stu2:(stu2)")//两者的地址是一样的
    

    我觉得一句话可以概括这种存储方式:“栈存变量,堆存对象”,这种方式很好的利用了栈的存取速度快的特点,堆存量大的特点。

    有点像我装了一个固态硬盘和机械硬盘,然后把应用程序都装固态硬盘里,文件都存在机械硬盘里,然后每次打开应用,文件都是从机械硬盘读取的。

    2.NSString的错觉

     但是对NSString,我们容易产生错觉,比如我这样写:

        NSString *str1=@"str1";
        NSString *str2=str1;
        str2=@"str2";
        NSLog(@"str1:%@----str2:%@",str1,str2);//输出前者str1,后者str2

     为毛str2的修改还是不影响str1呢?说好的指针呢?这是因为通过=@""方式赋值,事实上已经重新开辟了内存,然后让str2指向这个新地方,所以str2的修改肯定就不会影响str1。里需要注意下的是,NSString对象是直接存在栈里面的。很多基本的数据类型都会存在栈里,这样加快访问速度。

    可以通过输出指针所在地址和指针指向地址来进行分析:

        NSString *str1=@"str1";
        NSString *str2=str1;
        NSLog(@"str1:%p----str2:%p",str1,str2);//内容地址,显示一样,说明都指向@“str1”
    
        
        str2=@"str2";
        NSLog(@"str1:%p----str2:%p",str1,str2);//内容地址,显示不一样,说明str1所指内容不变,str2所指内容已经变化
        
        NSLog(@"str1:%@----str2:%@",str1,str2);//输出前者str1,后者str2

    以下的方法,实际上也都并不是拷贝一份,因为编译器对此做了优化,使几个指针变量指向的同一个内存区域

        NSString *string1=@"hello";
        NSString *string2 = [[NSString alloc]initWithString:string1];  
        NSString *string3 = [NSString stringWithString:string1];
    

    可见,NSString类变量都是遵循这样的准则:"指针A赋值给指针B,两者指向同一块内存,修改后重新指向开辟新内存"

  • 相关阅读:
    人工智能是什么?我来告诉你!
    【计算机网络】--路由控制
    【计算机网络】-中间系统到中间系统(isis)
    【计算机网络】-边界网关协议(BGP)
    《Linux就该这么学》—非常适合linux技术学习的入门好书
    ip路由原理、实施静态路由、实施rip
    python 冒泡排序动态图解
    小球100米反复上下跳;反转字符串单词
    django.db.utils.InternalError: (1054, "Unknown column 'cid' in 'field list'")
    'webpack-dev-server' 不是内部或外部命令,也不是可运行 的程序 或批处理文件。
  • 原文地址:https://www.cnblogs.com/rayshen/p/5007758.html
Copyright © 2011-2022 走看看