objectivec讲义.docx
《objectivec讲义.docx》由会员分享,可在线阅读,更多相关《objectivec讲义.docx(109页珍藏版)》请在冰豆网上搜索。
objectivec讲义
重点:
基本类型、表达式、循环、作用域
难点:
理解作用域和掌握循环和switch中的容易出错的地方
准备作业:
实现一个简单的九九乘法表
教学目的与要求:
掌握OC的基本语法,能够熟练使用循环
结构。
课时安排与讲授方法:
课后小结:
第一章基本语法
主要内容:
·标示符
·关键字
·oc基本数据类型
·运算符
·表达式和语句
·分支和循环
·变量的作用域
标示符
•oc语言中,对各种变量、方法和类等要素命名时使用的字符序列称为标示符。
•oc标示符有如下命名规则:
•标示符由字母、下划线“_”、美元符“$”和数字组成
•标示符必须以字母、下划线、美元符号开头
•oc标示符大小写敏感,长度无限制
•约定俗成:
oc标示符选取要“见名知意”,并且不能与oc中保留字重名。
标示符
•oc语言中,对各种变量、方法和类等要素命名时使用的字符序列称为标示符。
•oc标示符有如下命名规则:
•标示符由字母、下划线“_”、美元符“$”和数字组成
•标示符必须以字母、下划线、美元符号开头
•oc标示符大小写敏感,长度无限制
•约定俗成:
oc标示符选取要“见名知意”,并且不能与oc中保留字重名。
·oc中一些具有特定含义的,系统专门使用的字符串称为“保留字”,或者叫“关键
字”(keyword).
·oc中的关键字全部都是小写。
OC常量
•oc中的常量值用字符串表示,区分不同的数据类型
•如整型常量:
3456
•实型常量:
3.1415926
•字符常量:
‘a’
•逻辑常量:
true、false
•字符串常量:
“helloiphone”
•注意:
•区分字符常量和字符串常量
·oc变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。
·oc程序中每一个变量都属于特定的数据类型,在使用前必须对其声明,声明格式为:
typevarName[=value];
·例如:
inti=580;
floatf=12.12f;
·doubled=0.798;
·NSString*s=@”helloiphone”;
·从本质上讲,变量其实是内存中的一小块区域,使用变量名来访问这块区域,因
此,每一个变量使用前必须要先申请(声明),然后必须进行赋值(填充内容),才能
使用。
·按被声明的位置划分:
·局部变量:
方法或语句块内部定义的变量
·实例变量:
方法外部、类的内部定义的变量
·按所属的数据类型划分:
·基本数据类型变量
·指针数据类型变量
·方法体内部声明的变量(包括形参)称为局部变量:
方法体内部是指与方法对应的大括号内部
·在方法体外,类体内声明的变量成为“实例变量”或者“成员变量”
-(void)getName
{
inta;
intb=a+5;//编译警告,变量a还未被初始化
floatc=2.8;
}
·int:
声明整型变量
·double:
声明双精度变量
·float:
声明浮点型变量
·char:
声明字符型变量
·id:
通用的指针类型
·enum:
声明枚举类型
·long:
声明长整型变量或函数
·short:
声明短整型变量或函数
·signed:
声明有符号类型变量
·struct:
声明结构体变量
·union:
声明共用体(联合)数据类型
·unsigned:
声明无符号类型变量
·void:
声明函数无返回值或无参数
·oc中整数类型用int来表示,格式化符号用%i或d%来表示
·比如:
inta=100;
·oc语言的整型常量默认为int型,声明long型常量可以后加‘l’或‘L’,如:
intb=600;//正确longc=88888888888L;
·浮点类型的变量可以存储包括小数的值
·oc中有两种浮点类型
·float有效数字为6~7位,格式化说明符号用%f表示
·double有效数字为15~16位格式化说明符号用%f,%e或%g表示
·oc中浮点型常量默认为double型,如果要声明一个常量为float,在数字的后面加f或
F。
·doublem=3.14159;//正确floatf=3.14f;
·下面列出oc的各种浮点类型
·char型数据用来表示通常意义上的”字符”,格式化说明符用%c表示
·字符常量为用单引号括起来的单个字符,例如:
·charachar=‘a’;charb=‘0’;charcChar=‘苹’;值域范围:
-128~127
·“\n”,oc编译器把这个当作单个字符
·unsignedchar值域范围:
0~255
·oc字符采用Unicode编码,每个字符占两个字节,因而可用十六进制编码形式表示,
例如:
·charc1='\u0061';
·注:
Unicode是全球语言统一编码
•Boolean类型指的是用于存储真值和假值的变量,一般用于程序流程控制。
•Boolean类型数据允许取值true或false,也可以是0或非0的整数替代true和false,这
点和java语言不同。
实例:
Booleanflag=true;
if(flag)
{
NSLog(@”HelloiPhone”);
}
•longint:
声明变量xx为long的整型变量。
格式化符为%li,如:
longinta;
•longlongint:
声明变量xx为longlong的整型变量,格式化符%lli,如:
longlongintb;
•longdouble:
跟int基本相同
•unsignedint:
声明无符号的整型变量.如:
unsignedintc;
•signedint:
声明有符号的整型变量.如:
signedintd;
·告诉编译器没有任何范围类型的值
·不能像其他数据类型一样来声明变量
·例如:
voidi=10;//错误
·void通常与方法一起搭配使用,比如:
-(void)test
{
//code
}
id类型是oc中独有的数据类型,它可以存储任何类型的对象,从某种意义上说,它就是一般的对象类型。
•将number声明为id类型的变量。
如:
idnumber;
•格式化说明符:
%p
•oc中可以从任意基本数据类型转型到另外的基本类型
•转换分为默认转换和强制转换
•整型,字符型,浮点型的数据在混合运算中相互转换,转换时需遵循以下原则:
•容量小的类型默认转换为容量大的数据类型;数据类型按容量大小排序为:
•Byte,short,char-->int-->long-->float-->double
•Byte,short,char之间不会互相转换,他们三者在计算时⾸首先会转换成int类型。
•容量大的数据类型转换成容量小的数据类型,要加上强制转换符,但可能造成精度降低
或溢出;使用时要格外注意。
•实数常量(如:
2.9)默认为double,整数常量(如:
123)默认为int
OC语言支持如下运算符:
·算术运算符:
+,-,*,/,%,++,--
·关系运算符:
>,<,>=,<=,==,!
=
·逻辑运算符:
!
,&,|,^,&&,||
·位运算符:
&,|,^,~,>>,<<,>>>
·赋值运算符:
=
·扩展赋值运算符:
+=,-=,*=,/=
-(void)getNumber
{
inti1=10,i2=12;
inti=i2++;
NSLog(@"i=%d",i);
NSLog(@"i2=%d",i2);
i=++i2;
NSLog(@"i=%d",i);
NSLog(@"i2=%d",i2);
i=--i1;
NSLog(@"i=%d",i);
NSLog(@"i1=%d",i1);
i=i1--;
NSLog(@"i=%d",i);
NSLog(@"i1=%d",i1);
}
逻辑运算符:
!
:
逻辑非&:
逻辑与|:
逻辑或^:
逻辑异或&&:
短路与
||:
短路或
赋值运算符(=)
·当“=”两侧数据类型不一致时,可以适用默认类型转换或使用强制类型转换原则进
行处理
longl=100;inti=(int)l;
·注意:
可以将整型常量直接赋值给Byte,short,char等类型变量,而不需要进行强制
类型转换,只要不超出其数值范围
Byteb=11;charc=456;
XBytebb=23;Xshorts=-32769;
表达式:
·表达式是符合一定语法规则的运算符和操作数的序列
·a
·1.0+a
·(a-b)*c-1
·i<10&&i%10!
=0
·表达式的类型和值
·对表达式中操作数进行运算得到的结果称为表达式的值。
·表达式值的数据类型即为表达式的类型。
·表达式的运算顺序
·应按照运算符的优先级从高到低的顺序进行。
·优先级相同的运算符按照事先约定的结合方向进行。
·三目条件运算符,语法格式:
·x?
y:
z
·其中x为Boolean类型表达式,先计算x的值,若为true,则整个三目运算的结果为表达
式y的值,否则整个运算结果为表达式z的值。
·比如:
·intscore=80;intx=-100;
·NSString*type=score<60?
“不及格”:
“及格”;
·intflag=x>0?
1:
(x==0?
0:
-1);
·NSLog(@”type=”+type);
·NSLog(@”flag=”+flag);
·条件语句-根据不同条件,执行不同语句
·if
·if...else
·if...elseif
·if...elseif...elseif...else
·switch
·循环语句-重复执行某些动作
·for
·while
·do...while;
·if(表达式)//语句比如:
if(天不下雨)我就去打篮球
·if...else...
·if...elseif...
·if...elseif...elseif...
·if...elseif...elseif...else
·只有一句需要执行的语句时,可以省略{},为了是代码可读性更好,但是不推荐省略。
·for语句为如下形式:
for(表达式1;循环条件;表达式2)
{
//语句;⋯;
}
·执行过程
先求表达式1的值,再求循环条件的值,如果条件
不满足(即表达式为false),循环立即终止。
然后执行在
循环之后的程序语句。
如果条件满足,继续执行循环条
件的值,如果条件满足,执行表达式2如此重复执
行,直到条件不满足,退出循环。
·while语句为格式:
while(逻辑表达式){语句;
⋯;}
·执行过程
先判断逻辑表达式的值。
若为
true.则执行其后面的语句,然后再次
判断条件并反复执行,直到条件不成
·while语句为格式:
do{语句;}while(逻辑表达
式);
·执行过程
先执行语句,再判断逻辑表达
while、break和continue实例
switch(条件语句)
switch()
{
casexx:
⋯.
casexx:
⋯.
default:
⋯.
}
·小心case穿透,推荐使用break语句与之搭配使用
·多个case可以合并到一起
·default可以省略,但不推荐省略
·switch的值必须是int类型
代码格式规范
·大括号要对齐
·遇到{Tab缩进
·方法和程序块之间加换行
·运算符两侧加空格
·{前面有空格
·{}成对出现
第二章:
OC之面向对象编程
重点:
类与对象的概念对象与指针
难点:
理解对象指针以及self和super是难点
准备作业:
实现汽车对象的设计与使用
教学目的:
熟练掌握面向对象概念和基本用法
课时安排与讲授方法:
课后小结:
核心内容
·面向过程与面向对象的设计思想的区别
·类与对象的概念·类与类之间的关系
·对象和指针·如何定义一个类
·初始化方法·对象的创建和使用
·self和super关键字·static关键字
·@class和import的使用
·类的继承·访问权限的控制·方法的重写
·NSObject类·类的封装·类的多态
面向对象与面向过程设计思想
·设计一个下棋的游戏
·面向过程的解决方式是分析问题的步骤,然后每个步骤用分别的函数来解决。
1.开始2.绘制棋盘3.黑子先下4.白子再下5.如此循环往复6.判断输赢7.给出结
果
·面向对象的解决方式是讲他们划分为若干功能,而不是步骤
1.黑白双方2.棋盘系统(绘制棋盘)3.规则系统(判断输赢)
·类是对同一类事物高度的抽象,类中定义了这一类对象所应具有的静态属性(属性)和动态
属性(方法)。
·对象是类的一个实例,是一个具体的事物。
·类与对象是抽象与具体的关系。
·类其实就是一种数据类型,它的变量就是对象。
·A是B
·如果这句话能说的通,在设计程序的时候就可以看成是继承关系。
·对象是oc程序的核心,“万事万物皆对象”是程序中的核心思想。
·类是用来创建同一类型的对象的“模版”,在一个类中定义了该类对象所具有的成员变
量以及方法。
·类可以看成是静态属性(实例变量)和动态属性(方法)的结合体。
·iOSSDK里面提供了大量供编程人员使用的类,编程人员也可以定义自己的类。
OC类的声明与实现
@interfacePerson:
NSObject
{
//实例变量声明
intidentify;
intage;
}
//方法声明
-(id)initWithAge:
(int)_ageidentify:
(int)_identify;
-(int)getIdentify;
-(int)getAge;
-(void)setAge:
(int)_age;
@end
·类的声明放在”类名+.h”文件中。
·如:
Person.h文件。
·类的声明主要由两部分组成:
实例变量和方法。
·声明实例变量的格式:
变量类型变量的名称
·如:
intage;
实例变量
·实例变量可以使用oc语言中任何一种数据类型(包括
基本类型和指针类型)
·在声明实例变量的时候不能为其初始化,系统默认会
初始化。
·实例变量的默认作用域范围是整个类。
方法的声明
·oc语言中采用特定的语言调用类或者实例(对象)的方法称为发送消息或方法调用。
·oc中方法的调用有两种:
·[类名或对象名方法名];
·对象名.方法名;(点语法,后面再讲)
类的实现
@implementationPerson
-(id)initWithAge:
(int)_ageidentify:
(int)_identify
{
if(self=[superinit])
{
age=_age;
identify=_identify;
}
returnself;
}
-(int)getIdentify
{
returnidentify;
}
-(int)getAge
{
returnage;
}
-(void)setAge:
(int)_age
{
age=_age;
}
@end
Objective-c的指针
对象的创建和使用
·oc中对象通过指针来声明。
如:
ClassA*object;
·oc中对象的创建,使用alloc来创建一个对象。
编译器会给object对象分配一块可用的内存
地址。
然后需要对对象进行初始化即调用init方法,这样这个对象才可以使用。
如:
·Person*person=[Personalloc];
·person=[personinit];
·同一类的每个对象有不同的实例变量的存储空间.
·同一类的每个对象共享该类的方法.
·方法嵌套的形式来调用,如:
·ClassA*object=[[ClassAalloc]init];
对象的初始化
·对象必须先创建,然后初始化,才能使用。
·NSObject*object=[[NSObjectalloc]init];
首先为对象分配内存地址,为初始化做准备。
初始化是对象创建过程中将新分配对象的
状态设置为合理的初始值、使之处于可用状态的阶段。
通过约定,我们要求初始方法以init
开头,并且在成功完成初始化后,返回一个动态类型对象(id),如果失败则返回nil。
初始
方法可以包含一个或多个参数用于指定初始值。
如下所示:
·-(id)initWithArgument:
(int)arg;
·-(id)initWithArgument1:
(int)arg1xxWithArgument2:
(int)arg2;
初始化方法的实现
-(id)init
{
self=[superinit];
if(self)
{
//initcode
}
returnself;
}
·在一个类里面,具有最完整的初始化参数的初始化方法通常就是指定初始化方法。
子类的初始化方法必须调用父类的指定初始化方法,通过向super发送相应的消息初始化父类。
相反,它们将调用参数比自己多的其他初始化方法(通过向self发送消息),并为自身没有的参数提供初始
值。
在此调用序列中,最终将会调用到指定初始化方法,完成整个初始化过程。
指定初始化方法
·当没有指定初始化方法的时候,编译器为类自动添加init方法,如果有,编译器就不再添加。
·Person*person=nil;
·person=[[Personalloc]init];
intmain(intargc,constchar*argv[])
{
@autoreleasepool{
//insertcodehere...
Person*person=[[Personalloc]
initWithAge:
30identify:
@"3622234342343"];
intage=28;
[personsetAge:
age];
[personsetAge:
++age];
}
return0;
}
约定俗称的命名规则
·类名首字母大写
·变量名和方法名首字母小写
·使用驼峰标示
课堂练习
Person*p1=[[Personalloc]initWithAge:
30
identify:
32432423123];
intage=20;
Person*p2=[[Personalloc]initWithAge:
25
identify:
45565623123];
//age的值不变
[p1changeAge:
age];
NSLog(@"age:
%d",age);
//p1的值不变
[p1changeInfo:
p1];
NSLog(@"behind_person:
%page:
%d",p1,[p1getAge]);
//真正改变p2对象的值
[p1changed:
p2];
NSLog(@"p2age:
%d",[p2getAge]);
self和super关键字
·self指的是类对象本身
·super是父类对象本身
·self用来调用本类对象的方法
·super调用父类的方法
·self是类的隐藏的参数,指向当前调用方法的类,另一个隐藏参数是_cmd,代表当前
类方法的selector。
·super并不是隐藏的参数,它只是一个“编译器指示符”,它和self指向的是相同的消
息接收者。
·当使用self调用方法时,会从当前类的方法列表中开始找,如果没有,就从父类中再
找;而当使用super时,则从父类的方法列表中开始找,然后调用父类的这个方法。
为了解决循环引用导致的死锁问题。
@class和#import
·为什么会有这两个指令?
·他们的区别是什么?
·import会包含这个类的所有信息,包括实体变量和方法,而@class只是告诉编译器,其后面声明的名称是类的名称,至于这些类是如何定义的,暂时不用考虑,后面会再告诉你。
·在头文件中,一般只需要知道被引用的类的名称就可以了。
不需要知道其内部的实体变量和方法,所以在头文件中一般使用@class来声明这个名称是类的名称。
而在实现类里面,因为会用到这个引用类的内部的实体变量和方法,所以需要使用#import来包含这个被引用类的头文件。
·如果有循环依赖关系,如:
A->B,B->A这样的相互依赖关系,如果使用#import来相互包含,那么就会出现编译错误,如果使用@class在两个类的头文件中相互声明,则不会有编译错误出现。
所以,一般来说,@class是放在interface中的,只是为了在interface中引用这个类,把这个类作为一个类型来用的。
在实现这个接口的实现类中,如果需要引用这个类的实体变量或者方法之类的,还是需要import
设置器和访问器
在OC中get这个词有着特殊的含义,因此,不要用get方法命名。
property属性
(1)简化设置器和访问器。
注意两个关键字“@property”“@synthesize”
@property和@synthesize
·在@property()括号中,可以填写的属性:
·readwrite:
默认
·readonly:
只读,意味着没有set方法
·assign:
默认,引用计数不增加,
·retain:
引用计数增加1
·原子性:
actomic默认。
·非原子性:
nonatomic
·atomic是oc中的一种线程保护技术,是防止在未完成的时候,被另外一个线程使用,造成数据错误。
(2)点语法
self.myNumber=10;//设置self.myNumber;//访问
static关键字
·类体内的全局变量声明:
staticintgCount=0;
@interfaceClassA:
NSObject
{intx