【黑马程序员】OC之self关键字的介绍

本文介绍了Objective-C中的self关键字,包括self在实例方法和类方法中的使用,以及self修饰变量的重要性。通过实例展示了self如何调用其他实例方法、类方法,并解释了在setter方法中避免变量覆盖的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

1、self和super 关键字的介绍

 

       1, self  super 简介

       在 C++  C# 等高级面向对象的语言中有一个 this 指针用来描述当前对象。  OC 中同样也有 self 表示当前对象,  C++ 语言中的 this 指针含义一样

       在 OC 中, 提供了两个保留字, 一个是 self, 另一个是 super。

       在实例方法中, self 就是当前对象 self 发送消息, 即给当前对象发送消息,调用方法 super 发送消息,则是给其父类发送消息,调用父类的方法。

       2, self 的应用场景

       1) 使用在类方法中

       2)使用在实例方法中

       3)访问成员变量

       4) OC 内存管理中有特殊用法

 

2、self 在实例方法中的使用

 

       1, 在实例方法中表示当前对象

       在实例方法中, self 就是当前对象使用对象允许访问实例变量或其他实例方法。

       2, 在实例方法中调用另一个实例方法

       例如有一只狗, 即创建一个 Dog 类。 然后,它有叫的方法(bark),也有吃的方法(eat)。

       那么实现,当狗吃完东西后就叫,来提示吃完了。 

@interface Dog : NSObject

 

- (void)bark;

- (void)eat;

 

@end

 

@implementation Dog

 

- (void)bark {

    NSLog(@"汪汪汪吃完了...");

}

- (void)eat {

    NSLog(@"吃狗粮...");

    [self bark];

}

 

@end

       在eat实例方法中利用self调用bark这个实例方法,实现了狗吃完东西就叫表示吃完了这个功能。 

       3, self 就是当前对象

@interface Dog : NSObject

 

- (void)bark;

- (void)eat;

 

@end

 

@implementation Dog

 

- (void)bark {

    NSLog(@"汪汪汪吃完了...");

    NSLog(@"bark  self 地址为 %p"self);

}

- (void)eat {

    NSLog(@"吃狗粮...");

    [self bark];

    NSLog(@"eat  self 地址为 %p"self);

}

 

@end

 

 

int main(int argc, const char * argv[]) {

    @autoreleasepool {

        Dog *dog = [[Dog allocinit];

        [dog eat];

        NSLog(@"dog 的地址为 %p", dog);

    }

    return 0;

}

       运行的结果为:在运行结果中selfdog的地址是一样的,即self就是当前对象。

3、self 在类方法中的使用

       1, self 在类方法中含义与在实例方法中不一样

       可以添加一个类方法, 在类方法中打印出 self 的数据,发现与对象的地址完全不同(实际上,没有必要打印,思考一下,类方法是与对象实例无关的,当然无法打印地址)。

       在实例方法中,self 表示的实际上是当前类换句话说,利用 self 可以在类方法中调用其他类方法。

       2, 使用 self 调用类方法

       既然 self 就是类,那么调用类方法,就是对 self 发送消息

@interface MyClass : NSObject

 

+ (void)method1;

+ (void)method2;

 

@end

 

@implementation MyClass

 

+ (void)method1 {

    NSLog(@"我是类方法 method1");

}

+ (void)method2 {

    NSLog(@"我是类方法 method2");

    

    [self method1];

}

 

@end

        在类方法method2self调用了类方法method 1,实现了用self来调用类方法。

 

4、self 修饰变量

 

       1, 问题的引出

 

       如果类中提供的实例变量与其 setter 方法中提供的参数名一样,如何处理赋值呢

       下面引入一个案例,假设有一个 Dog 类,里面提供一个实例变量 _speed 表示速度,然后

@interface Dog : NSObject {

    int _speed;

}

 

- (int)speed;

- (void)setSpeed:(int)speed;

 

@end

 

@implementation Dog

 

- (int)speed {

    return _speed;

}

- (void)setSpeed:(int)speed {

    _speed = speed;

}

 

@end

 

 

int main(int argc, const char * argv[]) {

    @autoreleasepool {

        Dog *dog = [[Dog allocinit];

        [dog setSpeed:120];

        NSLog(@"小狗以 %d 的速度冲了出去", [dog speed]);

    }

    return 0;

}

        运行为:小狗以120的速度冲了出去

        当 setter 方法中参数名也是 _speed 时,修改 setter 方法

- (void)setSpeed:(int)_speed {

    _speed = _speed;

}

 

       运行的结果为:小狗以 的速度冲了出去

       这个时候问题出现了,两次小狗出去的速度不一样,也就是说并没有被赋以速度值。

       2, 分析

       在方法中,声明的参数 _speed 是局部变量,它隐藏了全局作用的 实例变量,因此无法获得数据,所赋值也没有作用到实例变量中。

       3, 改用 self 引用该变量

       修改 setter 方法

- (void)setSpeed:(int)_speed {

    self->_speed = _speed;

}

      运行结果为:小狗以120的速度冲了出去

      通过对比知道可以利用self来修饰变量获得数据完成赋值。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值