objective-c 关于self的用法总结

简介:
何时使用 self. 在网上搜索或者论坛里的回复大多都是简简单单的说这与 objc 的存取方法有关,如何与存取方式有关究竟他们之间的是什么样的关系就很少有同学回答了。下面以代码来说明问题


创建一个 Student 类,继承 NSObject 类,代码:
   1:   #import <Foundation/Foundation.h>
   2:  
   3:   @ interface  Student : NSObject{
   4:  
   5:       NSString *idd;
   6:       NSString *name;
   7:   }
   8:   @property (nonatomic, retain) NSString *idd;
   9:   @property (nonatomic, retain) NSString *name;
  10:  
  11:   @end
.m文件 代码:
   1:   #import  "Student.h"
   2:  
   3:   @implementation Student
   4:   @synthesize idd,name;
   5:  
   6:   - ( void )dealloc
   7:   {
   8:       [idd release];
   9:       [name release];
  10:       [super dealloc];
  11:   }
  12:  
  13:  
  14:   @end
使用 @propety @synthesize 实现 Student 的成员属性的 set get 方法。通常我们在其他类里访问 Student 的成员属性的做法:
获取 student 的名字通过 student.name , 给名字赋值 [student  setName:@“jordy ”]; 其中 student Student 类对象,如果在 Student 类内部访问其成员属性使用 [self setName:@”jordy”], 访问使用 self .name ;
注意:上述的代码,由于wordpress的原因,代码中的字符会自动保存为中文格式。你在使用时记得改为英文格式。
Student.h Student.m 文件 ,是我们习惯性的写法,但似乎还是不能解释什么加 self 和不加 self 的区别,请看下面代码,是另一种习惯性的写法,还以 Student 类为例:
.h文件 代码:
   1:   #import <Foundation/Foundation.h>
   2:  
   3:   @ interface  Student : NSObject{
   4:  
   5:       NSString *_idd;
   6:       NSString *_name;
   7:   }
   8:   @property (nonatomic, retain) NSString *idd;
   9:   @property (nonatomic, retain) NSString *name;
  10:  
  11:   @end


.m文件 代码:
   1:   #import  "Student.h"
   2:  
   3:   @implementation Student
   4:   @synthesize idd = _idd;
   5:   @synthesize name = _name;
   6:  
   7:   - ( void )dealloc
   8:   {
   9:       [_idd release];
  10:       _idd = nil;
  11:       [_name release];
  12:       _name = nil;
  13:       [super dealloc];
  14:   }
  15:  
  16:  
  17:   @end

可以注意到上述代码,与之前的代码,在.h文件 name 变量改写为了 _name ;在.m文件中 @sythesize 的写法也发生了变化。
如果通过方法 self._name 获取属性的值,xcode编译器会 提示 错误,其实这也就说明了,我们通常使用 self.name 实际使用的是 student name get 方法,同理 name set 方法亦是如此。


接下来从内存管理来说明使用 self. 和不使用 self 的区别:
ViewController.h 文件,使用 Student 类,代码如下:
   1:   #import <UIKit/UIKit.h>
   2:   @ class  Student;
   3:  
   4:   @ interface  ViewController : UIViewController{
   5:       
   6:       Student *_student;
   7:   }
   8:  
   9:   @property (nonatomic, retain) Student *student;
  10:  
  11:   @end
ViewController.m 文件,代码:
   1:   #import  "ViewController.h"
   2:   #import  "Student.h"
   3:  
   4:   @implementation ViewController
   5:   @synthesize student = _student;
   6:  
   7:   - ( void )didReceiveMemoryWarning
   8:   {
   9:       [super didReceiveMemoryWarning];
  10:   }
  11:  
  12:   #pragma  mark -  View  lifecycle
  13:  
  14:   - ( void )viewDidLoad
  15:   {
  16:       [super viewDidLoad];
  17:   }
  18:  
  19:   - ( void ) dealloc
  20:   {
  21:       [_student release];
  22:       _student = nil;
  23:       [super dealloc];
  24:   }
其它的方法没有使用到,所以这里就不在 显示 了。
ViewController.m viewDidLoad 方法中创建一个 Student 类的对象
   1:   Student *mystudent = [[Student alloc] init];
   2:   self .student = mystudent;
   3:   [mystudent release];
这是相信有人会有疑问了,问什么创建student对象要这么复杂,似乎直接使用 self.student = [[Student alloc] init];  也没有问题,不加 self 有时也是挺正常的呀?
接下来就需要从内存角度来分析它们之间的区别了:
1、加 self 的方式:
Student *mystudent = [[Student alloc] init];       //mystudent 对象 retainCount = 1;
self .student = mystudent;   //student 对象 retainCount = 2;
[mystudent release];  //student 对象 retainCount = 1;
retainCount指对象引用计数,student的property 是retain 默认使用 self .student引用计数+1。
2、不加 self 的方式
Student *mystudent = [[Student alloc] init];       //mystudent 对象 retainCount = 1;
student = mystudent;   //student 对象 retainCount = 1;
[mystudent release];   //student 对象内存已释放,如果调用,会有异常
3、加 self 直接赋值方式
self .student = [[Student alloc] init];  //student 对象 retainCount = 2;容易造成内存泄露

由于objective-c内存管理是根据引用计数处理的,当一个对象的引用计数为零时,gcc才会释放该内存。

本文转自编程小翁博客园博客,原文链接:http://www.cnblogs.com/wengzilin/archive/2012/03/16/2400392.html,如需转载请自行联系原作者

相关文章
|
7月前
|
安全 编译器 Swift
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
430 2
|
5月前
|
开发工具 iOS开发 容器
【Azure Blob】关闭Blob 匿名访问,iOS Objective-C SDK连接Storage Account报错
iOS Objective-C 应用连接Azure Storage时,若不关闭账号的匿名访问,程序能正常运行。但关闭匿名访问后,上传到容器时会出现错误:“Public access is not permitted”。解决方法是将创建容器时的公共访问类型从`AZSContainerPublicAccessTypeContainer`改为`AZSContainerPublicAccessTypeOff`,以确保通过授权请求访问。
【Azure Blob】关闭Blob 匿名访问,iOS Objective-C SDK连接Storage Account报错
|
7月前
|
缓存 开发工具 iOS开发
优化iOS中Objective-C代码调起支付流程的速度
优化iOS中Objective-C代码调起支付流程的速度
125 2
|
7月前
|
安全 JavaScript 前端开发
IOS开发基础知识:介绍一下 Swift 和 Objective-C,它们之间有什么区别?
IOS开发基础知识:介绍一下 Swift 和 Objective-C,它们之间有什么区别?
313 0
|
iOS开发 容器
iOS 代码规范格式 Objective-C(上)
iOS 代码规范格式 Objective-C
440 0
iOS 代码规范格式 Objective-C(上)
|
编译器 API iOS开发
iOS 代码规范格式 Objective-C(下)
iOS 代码规范格式 Objective-C(下)
242 0
|
机器学习/深度学习 API iOS开发
【IOS 开发】Objective-C Foundation 框架 -- 字符串 | 日期 | 对象复制 | NSArray | NSSet | NSDictionary | 谓词(一)
【IOS 开发】Objective-C Foundation 框架 -- 字符串 | 日期 | 对象复制 | NSArray | NSSet | NSDictionary | 谓词(一)
184 0
|
存储 自然语言处理 Java
【IOS 开发】Objective-C Foundation 框架 -- 字符串 | 日期 | 对象复制 | NSArray | NSSet | NSDictionary | 谓词(二)
【IOS 开发】Objective-C Foundation 框架 -- 字符串 | 日期 | 对象复制 | NSArray | NSSet | NSDictionary | 谓词(二)
256 0
|
存储 安全 C语言
【iOS 开发】Objective - C 面向对象 - 方法 | 成员变量 | 隐藏封装 | KVC | KVO | 初始化 | 多态(一)
【iOS 开发】Objective - C 面向对象 - 方法 | 成员变量 | 隐藏封装 | KVC | KVO | 初始化 | 多态(一)
210 0
|
自然语言处理 Go iOS开发
iOS开发者知识普及,Swift 挑战 Objective-C,谁会笑到最后?
如果你的公司也正计划跟随 iOS 软件开发,那么你需要作出一个至关重要的决定。你需要为你的产品选择合适的技术组合。你的目标是什么?如果是原生应用开发而不是跨平台软件,你会选用哪种编程语言?久经考验的 Objective-C 还是 Swift?