zoukankan      html  css  js  c++  java
  • Objective-C 【self的用法】

    ———————————————————————————————————————————
    self和super关键字

    OC提供了两个保留字self和super,用于在方法定义中引用该执行方法的对象。

    OC中的self相当于C++、Java中的 this指针 。

    super发送消息可以将方法实现分发给其父类(实现父类的方法)


    ———————————————————————————————————————————
    self在对象方法中的使用

    举个例子:

    #import <Foundation/Foundation.h>

    @interface Dog : NSObject
    -(void)run;
    -(void)eat:(NSString *)foodName;
    @end

    @implementation Dog
    -(void)run
    {
        NSLog(@"run!!!");
        //如果我们想在调用run方法的内部调用eat:方法,那么我们可以创建一个新的实例对象,然后调用一下eat:方法。
    //    Dog *dog2=[Dog new];
    //    [dog2 eat:@"meat"];
        //但是我们知道,这时候调用两个方法的对象并不是同一个了,一个是dog1,一个是dog2。 那么如果我想让同一个实例对象去调用两个方法,该怎么办呢?这时候我们就要用到self关键字了。
        NSLog(@"self的地址:%p",self);//我们输出self的指针值,来查看他的地址
        [self eat:@"meat"];//结果发现,dog1的地址和self的地址是一样的,也就是这两个方法都是同一个实例对象调用的。
    //    ★★★所以说self在对象方法中使用时,其指代的是调用当前方法的对象★★★
    }
    -(void)eat:(NSString *)foodName
    {
        NSLog(@"eat %@ now!!!",foodName);
        
    }
    @end

    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            Dog *dog1=[Dog new];
            NSLog(@"dog1的地址:%p",dog1);//同样查看一下dog1的地址
            [dog1 run];
        }
        return 0;
    }


    ———————————————————————————————————————————

    self在类方法中的使用

    举个例子:

    #import <Foundation/Foundation.h>

    @interface Dog : NSObject
    +(void)run;
    +(void)eat;
    @end

    @implementation Dog
    +(void)run
    {
        NSLog(@"run!!!");
        NSLog(@"self的地址:%p",self);//在类方法内查看self的当前地址,结果与类的地址是一致的
        //★★★所以说,self在类方法中使用的时候指代的是其当前类★★★
        [self eat];
    }
    +(void)eat
    {
        NSLog(@"eat!!!");
    }
    @end

    int main(int argc, const char * argv[]) {
        @autoreleasepool {
    //        NSLog(@"查看Dog类的地址:%p",Dog);  这句话是错误的,显然查看类的地址不能用这种方式。如何去查看,用下面的方式
            
            Dog *dog=[Dog new];
            NSLog(@"Dog类的地址:%p",[dog class]);//[dog class]返回的就是当前类(类对象)的地址。什么是类对象,先不管他。
            
            [Dog run];
        }
        return 0;
    }


    ———————————————————————————————————————————
    self 修饰变量

    这一部分比较重要,我经过自己的总结做了详细的解释,希望大家好好的去理解,不明白的自己去敲一敲代码,帮助自己吃透这一部分的内容。

    举个例子:

    #import <Foundation/Foundation.h>

    @interface Dog : NSObject
    {
    //    int _speed;
        int speed;
    }
    -(void)setSpeed:(int)speed;
    -(int)speed;
    @end

    @implementation Dog

    //set方法
    //-(void)setSpeed:(int)speed
    //{
    //    _speed=speed;
    //}

    //get方法
    //-(int)speed
    //{
    //    return _speed;
    //}

    //当实例变量名和set方法形参名一样的情况下
    -(void)setSpeed:(int)speed
    {
    //    speed=speed;
    //    我们知道实例变量(类的属性成员)是整个类中都可以访问的,所以实例变量是全局变量。而方法的形参是在方法内作用的,所以方法的形参属于局部变量。那么如果在方法的内部定义了与全局变量同名的局部变量,那么局部变量会屏蔽全局变量的作用域。
    //    如在上面的一行代码   speed=speed;  我们知道前面的应该是实例变量,后面的是函数传过来的局部变量。但是由于同名,局部变量屏蔽了实例变量的作用域,所以说上面其实是局部变量对局部变量的赋值
        
    //    局部变量     局部变量
    //    speed   =   speed  ;
        
    //    这就如同  int  a = 10 ;
    //             a = a ;
        
    //    所以说,在同名的情况上,上面的操作是错误的。
        
    //    那么我们应该怎么在实例变量名和set方法形参同名的情况下正确为实例变量赋值呢?显然,我们要用到self访问变量。
        self->speed=speed;
    }

    -(int)speed
    {
        return speed;
    }

    @end

    int main(int argc, const char * argv[]) {
        @autoreleasepool {
    //        Dog *dog=[Dog new];
    //        [dog setSpeed:99];
    //        NSLog(@"speed:%d",[dog speed]);
    //        上面的这些,都是可以正常运行的。先设置(set)实例变量的值,然后再读取(get)实例变量的值。
    //        我们知道,set方法中有一条注意事项就是 一般情况下实例变量名不能和set方法形参名一样。(我们一般在实例变量名前面加下划线,而set方法的形参名是去掉下划线的部分),但是这是指的一般情况下,其实我们是可以让他们一样的,下面我们主要由此来验证self修饰变量的一个用法
            
    //        Dog *d=[Dog new];
    //        [d setSpeed:90];
    //        NSLog(@"speed:%d",[d speed]);
    //        对于上面三行的代码,由于实例变量名和set方法的形参同名,所以说产生了错误,所以这里speed的结果是0
            
            Dog *dd=[Dog new];
            [dd setSpeed:88];
            NSLog(@"speed:%d",[dd speed]);
    //        上面三行代码,由于正确使用的self去访问变量,所以是正确输出的。
        }
        return 0;
    }


    ———————————————————————————————————————————
    self 的总结和注意事项

    谁调用当前方法,self就代表谁。

    self在对象方法中,self代表当前对象。
    self在类方法中,self代表当前类。

    同时有 对象方法 和 类方法 存在的时候(且同名),这个时候如果运用self,self也不会调用错误的!self是很聪明的!!!


    ———————————————————————————————————————————

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    SQL*PLUS命令的使用大全
    Oracle总结
    SQL*PLUS命令的使用大全
    Java经典面试题
    学习Java的30个基本概念
    Java经典面试题
    学习Java的30个基本概念
    Oracle总结
    ORACLE大数据量下的分页解决方法
    XAMPP修改80和443端口及创建虚拟目录
  • 原文地址:https://www.cnblogs.com/wzy294250051/p/4787896.html
Copyright © 2011-2022 走看看