self. 和 _ 的思考
来源:互联网 发布:淘宝上300块的投影仪 编辑:程序博客网 时间:2024/06/08 09:59
网上查找self. 和 _ 的区别的时候找到这个问题和答案,感觉答的非常棒,有助于理解,搬运过来。
http://bbs.csdn.net/topics/390922775?page=1
1
2
3
4
5
6
7
8
9
10
11
12
@property
(
nonatomic
, strong)
NSMutableArray
*programStack;
- (
NSMutableArray
*)programStack
{
if
(_programStack ==
nil
) _programStack = [[
NSMutableArray
alloc] init];
return
_programStack;
}
- (
void
)pushOperand:(
double
)operand
{
[
self
.programStack addObject:[
NSNumber
numberWithDouble:operand]];
// [_programStack addObject:[NSNumber numberWithDouble:operand]];
}
问题在这里(void)pushOperand
这个代码是按下确认后label上的数字压入array。
我用下面的下划线操作 这个array一直是null。
这个俩个不是等效的吗....求解释
答:
显然是不一样的。
主要是涉及到内存管理的问题。self.propertyName 使用self. 是对属性的访问。使用_ 是对局部变量的访问。
所有被声明为属性的成员,在ios5 之前需要使用编译器指令@synthesize 来告诉编译器帮助生成属性的getter,setter方法。之后这个指令可以不用人为指定了,默认情况下编译器会帮我们生成。 编译器在生成getter,setter方法时是有优先级的,它首先查找当前的类中用户是否已定义属性的getter,setter方法,如果有,则编译器会跳过,不会再生成,使用用户定义的方法。 也就是说你在使用self.propertyName 时是在调用一个方法。如你上面的例子:
Objective C code?
1
2
3
4
5
- (
NSMutableArray
*)programStack
{
if
(_programStack ==
nil
) _programStack = [[
NSMutableArray
alloc] init];
return
_programStack;
}
这是属性programStack的getter方法,是你定义的,上面提到编译器会跳过帮你生成getter方法,使用你自己在类中定义的。当我们使用self.programStack 来访问时这个getter方法就会被调用。
这个方法中做了什么? 它判断局部变量_programStack 是否为空,如果为空,创建实例,并返回。也就是说我们在使用self.programStack 时能保证它有实例,不为空
再看下面的这个方法,通过上面的说明,你应该能明白为什么使用 _programStack 来添加对象时,得到的是nil
Objective C code?
1
2
3
4
5
- (
void
)pushOperand:(
double
)operand
{
[
self
.programStack addObject:[
NSNumber
numberWithDouble:operand]];
// [_programStack addObject:[NSNumber numberWithDouble:operand]];
}
那是因为_programStack 局部变量本身指向的就是一个空对象nil. 而使用self.programStack 时,会调用上面的programStack方法,在这个方法中将_programStack指向了一个已实例的对象。
自己总结:假设_programStack和
- (
void
)pushOperand:(
double
)operand属于类SS,
在类SS外面的主程序中使用该类时,会创建该类s,但并不会初始化该类的变量programStack
,因此如果创建类后直接调用pushOperand方法时,
programStack变量是不曾初始化的。向一个不曾初始化的数组addObject自然是无效的。
如果在
- (
void
)pushOperand:(
double
)operand方法中使用
self
.programStack
时这个getter方法就会被调用。这个方法中做了什么? 它判断局部变量_programStack 是否为空,如果为空,创建实例,并返回。也就是说我们在使用self.programStack 时能保证它有实例,不为空。
而如果使用_programStack,这是类中的局部变量本身指向的就是一个空对象nil.并且未被初始化,因此无法成功。
因此 可以知道
[
self
.programStack addObject:[
NSNumber
numberWithDouble:operand]];
等效于
if (_programStack== nil) _programStack = [[NSMutableArrayalloc]init];
[_programStackaddObject:[NSNumbernumberWithDouble:operand]];
0 0
- self. 和 _ 的思考
- self 和 _的区别
- self.和_的区别(self和下划线的区别)
- self.***和_***的使用和区别
- self 和 _
- self.方法和_对变量的引用的区别
- self.属性名和_属性名的区别
- IOS 中self. 和_访问变量的区别
- ObjectiveC中的self.变量和_变量的区别
- self点语法和下划线_的区别
- iOS中_(下划线)和self.的区别
- self = [super init] 引发的思考
- Swift3.0 Self和self的区别
- new与alloc init,[NSArray array] 和 [[NSArray alloc]init] 及 self. 和 _ 的区别
- 关于self.与_的区别
- self以及"_"的使用-徐明伟
- ios 私有变量的发展历史以及self. 和 _的区别
- 『Python思考』数据检查和校验的函数_不断更新_不断改进
- 单例模式 详解
- LeetCode之Contains Duplicate
- Cocos2d-x从入门到精通第六课《自定义绘制》
- 图片旋转特征点的获取
- 华为机试题:逛动物园
- self. 和 _ 的思考
- 1128 -- 整数排序
- Android与js交互实例
- 设计模式的依赖倒转原则再理解
- Android Https相关完全解析 当OkHttp遇到Https
- 后端分布式系列:分布式存储-HDFS Client 设计实现解析
- 在c++中,vector是一个十分有用的容器,下面对这个容器做一下总结。
- PHP has xxx Problem
- Android开发工具--Android studio开发常用插件和工具