上一章我们主要学习了OC类和对象以及三大特性,对OC有了一定初步的认识和了解,本章主要进一步学习OC在实际开发中的开发技巧和核心语法。
第一讲 NSString和多文件开发的文件分工
1. NSString
在OC中NSString用来创建字符串,如NSString *str = @"jack";
最简单的创建字符串的方式
NSString *str = @"itcast";
char *name = "jack";
NSLog(@"我在%@上课", str);
注意OC字符串的输出用%@
创建OC字符串的另一种方式:
#import <Foundation/Foundation.h>
int main()
{
int age = 32;
int no = 5;
NSString *name = @"jack";
int size = [name length]; // length方法算的是字的个数(字数)
// 创建OC字符串的另一种方式:将字符串跟int数据合成一个新的字符串stringWithFormat方法
NSString *newStr = [NSString stringWithFormat:@"My age is %d and no is %d and name is %@", age, no, name];
return 0;
}
如代码中,创建OC字符串的另一种方式:将字符串跟int数据合成一个新的字符串stringWithFormat方法,注意stringWithFormat:这个方法的使用。
2. 多文件开发的文件分工
在实际的项目开发过程中,一个大型项目需要多人来共同完成,这样往往要进行文件的分工。
在学习老师的点和圆的练习视频后总结了多文件开发的文件分工的结论以及注意点:
(1)不管是include还是import里面不能放.m或者.c文件,只能放.h文件,.h 文件里面写函数声明
(2)只有利用类名调用类方法的时候,不需要在类名的后面写*。其他情况下,类名后面统一加上一个*
Circle *c1 = [Circle new];
- (BOOL)isInteractWithOther:(Circle *)other
(3)返回值是BOOL类型的,涉及到“是否XXX”,方法名一般都以is开头
- (BOOL)isInteractWithOther:(Circle *)other
(4)想拥有某个对象,就先创建对象,然后调用set方法将对象传递给内部的成员变量
// 创建圆心对象
Point2D *p1 = [Point2D new];
[p1 setX:13 andY:15];
// 先设置圆心
[c1 setPoint:p1];
(5)定义一个分2个文件:.h声明文件,和.m实现文件
.h:成员变量,方法的声明
.m:方法的实现
(6)如果想使用某一个类,只需要#import类的.h文件即可
第二讲 点语法和成员变量作用域
一、 点语法
1. 点语法的作用
OC设计点语法的目的,是为了让其他语言的开发者可以很快的上手OC语言开发,使用点语法,让它和其他面向对象的语言如java很像。
2. 点语法的本质
点语法的本质是方法的调用,而不是访问成员变量,当使用点语法时,编译器会自动展开成相应的方法。
切记点语法的本质是转换成相应的set和get方法,如果没有set和get方法,则不能使用点语法。
如:
stu.age=10;展开为:[stu setAge:10]; // 本质是set方法
int a=stu.age;展开为:[stu age]; // 本质是get方法
编译器如何知道是set方法还是get方法?主要是看是否赋值(可以使用断点调试来查看)。
在OC中访问成员变量只有一种方式即使用-> 如stu->age,这种情况要求在@public的前提下。
3. 点语法的使用注意
下面的使用方式是一个死循环:
(1)在set方法中,self.age=age;相当于是[self setAge:age];
(2)在get方法中,return self.age;相当于是[self age];
二、 成员变量的作用域
@public:在任何地方都能直接访问对象的成员变量
@private:只能在当前类的对象方法中直接访问 (@implementation中定义成员变量默认是@private,但一般很少这么做)
@protected:可以在当前类及其子类的对象方法中直接访问 (@interface中定义成员变量默认是@protected)
@package:只要处在同一个框架中,就能直接访问对象的成员变量 (这个不太常用)
注意:@interface和@implementation中不能声明同名的成员变量
@public在之前的学习初步阶段老师在成员变量之前都会加上是为了方便初学者,但随着学习的深入@public会暴露代码的内部结构因此除非特殊的情况不建议这么做。
@private只能在当前类的对象方法中直接访问,这句话指的是如果当前类@interface中声明的成员变量是@private类型,那么只能在当前类的@implementation中直接访问,在其子类或者其他地方都不能直接访问。
@protected在@interface中定义成员变量默认是@protected,可以在当前类及其子类的对象方法中直接访问,在其当前类和子类的@implementation的对象方法中可以直接访问。
第三讲 @property和@synthesize
@property和@synthesize这两个关键字是编译器特性,让xcode可以自动生成getter和setter的声明和实现。
1. @property关键字
@property 关键字可以自动生成某个成员变量的setter和getter方法的声明
比如:
@property int age;
编译时遇到这一行,则自动扩展成下面两句:
- (void)setAge:(int)age;
- (int)age;
注意:@property是用在@interface中,用来自动生成setter和getter的声明,用@property int age; 就可以代替上面的两行
2. @synthesize关键字
@synthesize关键字可以帮助生成成员变量的setter和getter方法的实现。
语法:@synthesize age = _age;
相当于下面的代码:
- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
}
注意:@synthesize关键字用在@implementation中,用来自动生成setter和getter的实现,用@synthesize age = _age;就可以代替上面的代码。
3. @synthesize关键字使用细节
*@synthesize age = _age;
setter和getter实现中会访问成员变量_age
如果成员变量_age不存在,就会自动生成一个@private的成员变量_age
*@synthesize age;
setter和getter实现中会访问成员变量age
如果成员变量age不存在,就会自动生成一个@private的成员变量age
*手动实现
若手动实现了setter方法,编译器就只会自动生成getter方法和不存在的成员变量
若手动实现了getter方法,编译器就只会自动生成setter方法和不存在的成员变量
若同时手动实现了setter和getter方法,编译器就不会自动生成不存在的成员变量
注意:@synthesize age = _age;这句代码@synthesize会访问_age这个成员变量,如果不存在,就会自动生成@private类型的_age变量,相当于在@implementation中生成成员变量
#import "Car.h"
@implementation Car
//会访问_speed这个成员变量,如果不存在,就会自动生成@private类型的_speed变量,相当于在@implementation中生成成员变量
@synthesize speed = _speed;
@synthesize wheels = _wheels;
// 下面这样同时写也是可以的
//@synthesize speed = _speed, wheels = _wheels;
- (void)test
{
NSLog(@"速度=%d", _speed);
}
@end
可以在main函数中利用断点调试和点语法来验证是否生成了成员变量以及是否生成了setter和getter方法
#import <Foundation/Foundation.h>
#import "Car.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Car *c = [Car new];
c.speed = 100; // 可以利用断点,查看到会自动生成了_speed的成员变量
[c test];
}
return 0;
}
4. @property新特性
自从Xcode4.4后,@property就独揽了@synthesize的功能,也就是说,@property可以同时生成setter和getter的声明和实现
默认情况下,setter和getter方法中的实现,会去访问下划线_ 开头的成员变量。
也就是说@property int age;这句话完成了3个功能:
(1)生成_age成员变量的get和set方法的声明;
(2)生成_age成员变量set和get方法的实现;
(3)生成一个_age的成员变量。
5. id关键字
id是万能指针,能指向或者说操作任何OC对象
注意:id后面不要加上 *
id是一种类型,变量名不能叫id,可以叫_id或者ID
id d = [Person new]; // id == NSObject * 学习时可以把id相当于NSObject *,因此任何继承于NSObject的都能操作
id的两种巧妙运用:
(1)void test(id d) // id作为函数参数时表示任何对象都能作为函数参数传进来
{
}
(2)@property id obj; // 这么写时表示成员变量是id类型,任何对象都能作属性,包括字符串
本章学习总结:
Xcode真的是一款非常强大的软件,苹果官方为其开发者设计的相应开发软件给开发者带来了很大的便利,让开发者能够不必花太多时间在垃圾代码上,就拿本章学习的知识来说,成员变量的getter和setter方法的声明跟实现可以说默写都能写出来,但是在实际应用开发中往往有很多的成员变量,setter和getter方法又不得不写,如果一行一行去写这种没有任何技术含量的代码势必要浪费很多时间在这种无聊的代码上,因此苹果官方利用@property和@synthesize来很好的解决了这一问题,给开发者带来了很大的便利。而且在Xcode4.4之后,做了更加的升级,@property就能独揽之前@synthesize的功能,让变成代码更为精简。
本章主要分为三讲知识,第一讲主要学习了NSString和多文件开发的文件分工,要掌握创建字符串的几种方式,还有NSString的一个很好用的方法stringWithFormat。另外,多文件开发的文件分工本章主要是做了一个总结,没有举实际的例子,例子要参照视频中点和圆的练习,需要掌握.m和.h文件的分工内容,同时要掌握BOOL类型的命名规范和创建对象时的注意事项。本章第二讲主要讲述点语法和成员变量的作用域,要掌握点语法的本质就是set和get方法,要注意和避免点语法中的死循环问题。成员变量的作用域问题要掌握那几个关键字的含义,特别是@private和@protected这两个,要掌握成员变量在什么情况下能够访问和什么情况下不能访问。本章第三讲主要学习了@property和@synthesize两个关键字,这两个关键字是编译器特性,让Xcode可以自动生成setter和getter方法的声明跟实现,照目前版本@property比较常用,因为其包括了@synthesize的功能,但是也要了解和掌握@synthesize的功能,注意@synthesize实际上就是帮助生成了setter和getter方法的实现,而@property则是可以同时生成setter和getter的声明和实现。要注意两个关键字的一些使用细节问题。此外本章还学习了万能指针id,能够操作任何OC对象,要掌握id在一些特定情况下的巧妙使用。