self.***和_***的使用和区别

简介: self.***和_***的使用和区别

很多人发现在大多数情况下使用self.和_没有区别,认为它们是等效的。实际上当是基本变量并且是本类内调用确实相同,但是self.可以调用父类的变量,_不可以;当它是对象指针时,它们有本质的区别。

当是对象指针时:

_***很简单就是调用本类的对象指针,而不调用对象的默认构造函数。

self.是调用本类(包括基类)的对象指针,会引起调用所指对象的默认构造函数,若你在引用的类中重写了默认构造函数,会调用它的重写的默认构造函数。所以你若不想构造函数要使用_;而你若使用self.并且你在所引用类重写了所指对象的默认构造函数,那么会引起循环调用而崩溃,所以绝对不能这样使用。当然若你想调用本子类没有的对象指针,而是父类的对象指针,那么你只能使用self.来调用父类的对象指针。

现在你明白了吧!简言之:_***不会调用所指对象的构造函数,类似本类内调用;self.会调用所指对象的构造函数并且可以调用父类的对象指针,类似整个类内调用。self.会引起循环调用get方法而引起崩溃,而_***不会引起崩溃。

综上所述:除了需要调用父类的变量和调用默认所指对象的构造函数并且保证使用类没有重写该类的默认构造函数的情况下才需要用到self.的调用;在block里只能使用self.,不能使用_***(不然会出现不能释放对象,有可能出现野指针,出现概率性崩溃)。

现在给你几个实际的例子,帮助区分它们的使用与区别。

下面看一个例子:

生命如下:@property (nonatomic, strong) HeadPanel *headPanel;

例子一会引起回环调用get方法而引起崩溃,所以使用self.前缀调用对象时要小心了:

-(HeadPanel *)headPanel{

    if (!(self.headPanel)) {
        self.headPanel = [[HeadPanel alloc] initWithFrame:CGRectMake(0, 20, kScreenWidth, 98)];
    }
    return self.headPanel;
}

崩溃时的截图如下:从左边显然看到时循环调用而引起崩溃:

例子二是正常不会引起异常:

-(HeadPanel *)headPanel{

    if (!(_headPanel)) {
        _headPanel = [[HeadPanel alloc] initWithFrame:CGRectMake(0, 20, kScreenWidth, 98)];
    }
    return _headPanel;
}

@property(nonatomic,assign) long processingOrderId;

在单例中的.h头文件中声明的非对象指针,要用_processingOrderId不要用self.processingOrderId,不然可能出现稀奇古怪的情况。

.h头文件中不声明orderId,在.m文件中有-(void)setOrderId:(long)orderId,在调用initData时会调用setOrderId:(long)orderId,编译器不报错的异常情况。

-(void)initData

{

self.orderId = -1;

}

-(void)setOrderId:(long)orderId

{

FLDDLogDebug(@”函数”);

_processingOrderId = orderId;

目录
相关文章
|
2月前
a++ 与 ++a 的区别
a++ 与 ++a 的区别
63 22
|
算法 Java Unix
C++基础语言之(二)C和C++的区别
C++基础语言之(二)C和C++的区别
106 0
|
9月前
|
数据可视化 数据挖掘
jupternotebook和jupterLab有什么区别?
jupternotebook和jupterLab有什么区别?
1156 0
|
安全
s=s+1,s+=1,++1,1++没有区别?
s=s+1,s+=1,++1,1++没有区别?
|
SQL Java 数据库连接
#{}与${}的区别
面试的时候经常碰到这样的题目:#{}和${}的区别是什么? 回答这样的问题首先要知道这两个符号是干嘛用的,然后再通过实例来解释两者的不同,这样才能更好的说服面试者。
177 0
c++ *和&的区别
c++ *和&的区别
355 0
|
存储 前端开发 Java
@SessionAttributes 和 @SessionAttribute的区别
@SessionAttributes 和 @SessionAttribute的区别
rsaCheckV2 和rsaCheckV1的区别分享
说明: 目前支付宝的SDK验签方法主要有两种一种是rsaCheckV1一种是rsaCheckV2 两种验签方法用于不同的接口的返回参数验签 1.rsaCheckV1验签方法   rsaCheckV1验签方法主要用于支付接口的返回参数的验签比如:当面付,APP支付,手机网站支付,电脑网站支付 这些接口都是使用rsaCheckV1方法验签的 2.
3651 11
|
关系型数据库
Where and Having区别
Where和Having的异同 (1)where是查询返回结果之前进行过滤的 (2)having是查询返回结果之后,对结果进行过滤的 (3)在SQL中增加 HAVING 子句原因是,where关键字无法与聚合函数一起使用,having子句常跟group by一同使用,过滤分组...
1518 0
|
容器 数据格式 XML
getMeasuredWidth和getWidth的区别
View的getWidth()和getMeasuredWidth()有什么区别吗? View的高宽是由View本身和Parent容器共同决定的。getMeasuredWidth()和getWidth()分别对应于视图绘制的measure和layout阶段。
1552 0