04.点语法
来源:互联网 发布:网络视频电话会议 编辑:程序博客网 时间:2024/05/29 11:06
在正式学习OC的点语法之前,先来看一下传统的get方法和set方法。定义一个Student类,拥有一个成员变量age和对应的get\set方法。
1.Student.h
1 #import <Foundation/Foundation.h>
2 3 @interface Student : NSObject { 4 int age; 5 } 6 7 - (void)setAge:(int)newAge; 8 - (int)age; 9 10 @end
2> 在第7、8行分别声明了age变量的set方法和get方法
2.Student.m
1 #import "Student.h" 2 3 @implementation Student 4 5 - (void)setAge:(int)newAge { 6 age = newAge; 7 } 8 9 - (int)age {10 return age;11 }12 13 @end
1> 在第5行实现了set方法
2> 在第9行实现了get方法
3.main.m
把定义好的Student类放到main函数中使用
1 #import <Foundation/Foundation.h> 2 #import "Student.h" 3 4 int main(int argc, const char * argv[]) 5 { 6 @autoreleasepool { 7 Student *stu = [[Student alloc] init]; 8 9 // 设置age的值10 [stu setAge:10];11 12 // 取出age的值13 int age = [stu age];14 15 NSLog(@"age is %i", age);16 17 [stu release];18 }19 return 0;20 }
1> 在2行包含Student的头文件
2> 在第7行创建Student对象,在第17行释放Student对象
3> 在第10行调用set方法设置age的值
4> 在第13行调用get方法获取age的值
5> 在第15行输出age的值
上面演示了OC传统get\set方法的简单用法,接下来使用点语法来代替。
前面main.m中main函数的代码可以改为:
1 int main(int argc, const char * argv[]) 2 { 3 @autoreleasepool { 4 Student *stu = [[Student alloc] init]; 5 6 // 设置age的值 7 stu.age = 10; // 等价于[stu setAge:10]; 8 9 // 取出age的值10 int age = stu.age; // 等价于int age = [stu age];11 12 NSLog(@"age is %i", age);13 14 [stu release];15 }16 return 0;17 }
1.注意第7行代码,把原来的[stu setAge:10]替换成了stu.age = 10。听清楚了,这两种写法是完全等价的。即这里的stu.age并不是代表直接访问stu对象的成员变量age,而是编译器遇到stu.age = 10的时候会自动将代码展开成[stu setAge:10]
再说,如果是直接访问成员变量的话,OC中应该是这样的语法:stu->age,而不是stu.age。
2.注意第10行代码,把原来的int age = [stu age]替换成了int age = stu.age。这两种写法又是完全等价的,stu.age并不是直接访问stu对象的成员变量age,而是编译器遇到int age = stu.age的时候会自动将代码展开成int age = [stu age]
3.因此,OC中点语法的含义跟Java是完全不一样的,OC点语法的本质是方法调用,不是直接访问成员变量。至于这个点语法代表的是get方法还是set方法,那就取决于你是取值还是设值,取值就是get方法(如第10行代码),设值就是set方法(如第7行代码)。
4.如果你想验证点语法是不是方法调用的话,有很多方法。
比如你可以在Student.m的set方法和get方法内部用NSLog加一些打印信息,如果程序运行后有输出打印信息,说明的确是调用了get方法或者set方法
1 #import "Student.h" 2 3 @implementation Student 4 5 - (void)setAge:(int)newAge { 6 NSLog(@"调用了setAge方法"); 7 age = newAge; 8 } 9 10 - (int)age {11 NSLog(@"调用了age方法");12 return age;13 }14 15 @end
三、点语法和self的陷阱
1.在Java中,this关键字代表着方法调用者,也就是说,谁调用了这个方法,this就代表谁。所以一般会这样写set方法:
1 public void setAge(int newAge) {2 this.age = newAge;3 }
第2行表示将newAge参数的值,赋值给方法调用者的成员变量age
2.OC中有个self关键字,作用跟this关键字类似。我这么说完,可能有人就会想这样写OC的set方法了:
1 - (void)setAge:(int)newAge {2 self.age = newAge;3 }
第2行中的self代表着当前调用setAge:方法的对象。但是第2行代码是绝对错误的,会造成死循环。因为我在前面已经说过了,OC点语法的本质是方法调用,所以上面的代码相当于:
1 - (void)setAge:(int)newAge {2 [self setAge:newAge];3 }
很明显,会造成循环调用setAge:方法,程序就这样崩溃了
四、一点小建议
如果是第一次接触OC的点语法,你可能会真的以为stu.age的意思是直接访问stu对象的成员变量age。其实,有一部分原因是因为我这里定义的Student类的成员变量名就叫做age。为了更好地区分点语法和成员变量访问,一般我们定义的成员变量会以下划线 _ 开头。比如叫做 _age 。
1.Student.h,注意第4行
1 #import <Foundation/Foundation.h> 2 3 @interface Student : NSObject { 4 int _age; 5 } 6 7 - (void)setAge:(int)newAge; 8 - (int)age; 9 10 @end
2.Student.m,注意第6行和第10行
1 #import "Student.h" 2 3 @implementation Student 4 5 - (void)setAge:(int)newAge { 6 _age = newAge; 7 } 8 9 - (int)age {10 return _age;11 }12 13 @end
// Person.h
// 点语法
#import <Foundation/Foundation.h>
@interface Person : NSObject {
int _age;
}
- (void)setAge:(int)age; // 方法名是setAge: 冒号也是方法名的一部分,oc中不能有
- (int)age; // 方法名是age
//方法名是setAge:andNo:
//- (void)setAge:(int)newAge andNo:(int)no;
@end
//
// Person.m
// 点语法
//
#import "Person.h"
@implementation Person
- (void)setAge:(int)age {
NSLog(@"调用了setAge方法:%i", age);
_age = age;
// 这是错误的写法,会导致死循环,无限调用set方法
// self.age = newAge;// [self setAge:newAge];
}
- (int)age {
NSLog(@"调用了age方法:%i", _age);
return _age;
}
@end
==============================
//
// main.m
// 点语法
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Person *person = [[Person alloc] init];
person.age = 10; // 等效于[person setAge:10];
int age = person.age; // 等效于int age = [person age];
NSLog(@"age is %i", age);
[person release];
}
return 0;
}
- 04.点语法
- 点语法
- 点语法
- 点语法
- 点语法
- 点语法
- 点语法
- 点语法
- OC语法--点语法
- description语法及点语法
- c++语法点
- [flex]点语法汇总
- 学习点plantuml语法
- Self 和点语法
- 点语法浅谈
- ios之点语法
- 2、点语法-OC
- ios点语法
- 算法复杂度分析
- 国外程序员推荐:每个程序员都应读的书
- nagios常见错误及页面错误
- position ="absolute" 与 position="fixed的异同"
- 如何在JavaScript与ActiveX之间传递数据(三)
- 04.点语法
- 使用PRId64
- Android开发者必知的5个开源库
- 字符串转换系列三:VARIANT、COleVariant 和_variant_t
- 求一元二次方程ax^2+bx+c=0的根
- 通过广域网(Intelnet)进行远程唤醒[或开机] 图解
- Android adb shell 获得点击屏幕的位置坐标
- C++快速学习笔记
- 無法將工作階段狀態要求送至工作階段狀態伺服器。請確定 ASP.NET 狀態服務已經啟動且用戶端與伺服器的通訊埠都相同。如果伺服器是在遠端電腦上,請檢查 HKEY_LOCAL_MACHINE\SYSTE