iOS 何时使用 self.
在 ObjC 的学习中经常会碰到是否应该使用 self 的苦恼,或者说什么时候使用全局变量,什
么时候 self ?
大多数的答案是:“这与 objc 的存取方法有关”
怎么样才能有关呢?接下来通过几个小例子来看一下。
首先我们创建一个学生类:Student 类
这个学生类里有学生的 id 和学生的姓名 name
1. #import
2.
3.
4. @interface
5. Student : NSObject{
6.
7. //idname
8.
9. NSString *id;
10.
11. NSString *name;
12. }
13.
14. @property
15. (nonatomic,strong) NSString *id;
16. @property
17. (nonatomic,strong) NSString *name;
18.
19. @end
20.
21. 学生类的实现文件
22.
23. #import
24. ""
25.
26. @implementation
27. Student
28.
29. @synthesize
30. id,name;
31.
32. @end
如果使用上面的方法来定义学生类的属性的 get、set方法的时候,那么其他类访问的
时候就是:
获取 student的名字通过 来获取,给名字赋值则使用[student
setName:@“eve”]; 其中 student 是 Student 类的对象,如果在 Student 类内部访问
其成员属性使用[self
setName:@”evo”], 访问使用 ;
上面的方法只是一种,但是很难解释 self 该不该使用。请看下面:
我们改写 Student 类
1. #import
2.
3.
4. @interface
5. Student : NSObject{
6.
7. //idname
8.
9. NSString *_id;
10.
11. NSString *_name;
12. }
13.
14. @property
15. (nonatomic,strong) NSString *id;
16. @property
17. (nonatomic,strong) NSString *name;
18.
19. @end
20.
21. .m文件
22.
23. #import
24. ""
25.
26. @implementation
27. Student
28.
29. @synthesize
30. id = _id;
31. @synthesize
32. name = _name;
33.
34. @end
可见这样的写法我们增加了_id和_name,其中@synthesize也有一定的变化。
如何这个时候使用 编译器就会报错,这样就说明了我们通常使用
实际使用的是 student 类 name 的 get 方法,同理 name 的 set 方法亦是如此。
另外网络上也有人从内存管理方面来说明的,我将其剪切出来以供学习:
文件,使用 Student 类,代码如下:
1. #import
2. @
3. class Student;
4.
5. @
6. interface ViewController : UIViewController{
7.
8. Student *_student;
9. }
10.
11. @property
12. (nonatomic, retain) Student *student;
13.
14. @end
15.
16. 文件,代码:
17.
18. #import
19. ""
20. #import
21. ""
22.
23. @implementation
24. ViewController
25. @synthesize
26. student = _student;
27.
28. -
29. (void)didReceiveMemoryWarning
30. {
31.
32. [super didReceiveMemoryWarning];
33. }
34.
35. #pragma
36. mark - View lifecycle
37.
38. -
39. (void)viewDidLoad
40. {
41.
42. [super viewDidLoad];
43. }
44.
45. -
46. (void) dealloc
47. {
48.
49. [_student release];
50.
51. _student = nil;
52.
53. [super dealloc];
54. }
55. 其它的方法没有使用到,所以这里就不在显示了。
56.
57. 在 的 viewDidLoad方法中创建一个 Student类的对象
58.
59. Student
60. *mystudent = [[Student alloc] init];
61.
62. = mystudent;
63. [mystudent
64. release];
接下来就需要从内存角度来分析它们之间的区别了:
1、加 self 的方式:
1. Student
2. *mystudent = [[Student alloc] init]; //mystudent 对象
3. retainCount = 1;
4.
5. = mystudent; //student 对象 retainCount = 2;
6. [mystudent
7. release];//student 对象 retainCount = 1;
8. retainCount指对象引用计数,student的 property
9. 是 retain 默认使用 引用计数+1。
2、不加 self 的方式
1. Student
2. *mystudent = [[Student alloc] init]; //mystudent 对象
3. retainCount = 1;
4. student
5. = mystudent; //student 对象 retainCount = 1;
6. [mystudent
7. release]; //student 对象内存已释放,如果调用,会有异常
3、加 self 直接赋值方式
= [[Student alloc] init];//student 对象 retainCount =
2;容易造成内存泄露
由于 objective-c 内存管理是根据引用计数处理的,当一个对象的引用计数为零时,gcc
才会释放该内存
个人总结:只需要在属性初始化的时候使用 self.属性,其他时候直接使用属性名就行;
使用 self.是 使 retaincount+1,为了确保当前类对此属性具有拥有权
个人使用习惯:
1. @interface CustomClass : UIViewController
2. {
3. NSString *str
4. }
5. @property (retain, nonatomic) NSString *str; @implementation CustomCla
ss @synthesize str; -(void)viewDidLoad
6. { // 方 法 一 用 alloc 必 须 手 动 释 放 一
次 = [[NSString alloc]initWithString:@"my str"];
7. [str release]; // 方 法 二 用 类 方 法 不
用 = [NSString stringWithString:@"my str"];
8.
9. 以后调用时直接使用 str,不必使用
10. [str appendString:@"\n"];
11. } //在 dealloc中必须释放 - (void)dealloc
12. { //方法一 [str release];
13. str = nil; //方法二 = nil;
14.
15. [super dealloc];
16. }
iOS何时使用self.