---------------------- IOS培训.期待与您交流! ----------------------
OC语言学习笔记一
---既然决定14年要好好的努力一次,那么就不要再轻言放弃,不再在随波逐流。只有努力过、拼搏过,才会知道自己行还是不行!为自己加油!---
---总结的知识点可能有不正确的地方,如果有发现请留言给我,我一定及时更正,不让错误的知识去误导大家,有好的意见也可大声提出来,小弟一定愿意采纳---
完全兼容C 在C的基础上,增加一层面向对象的语法 可以在OC中嵌入C C++代码
OC语法预览
1、关键字:基本所有关键字都是以@开头
2、字符串:字符串以@开头 如 @"Hello" OC中的字符串 C中字符串为"Hello"
3、OC基本数据类型:char、 int 、float、double 。BOOL(YES\NO) 布尔类型(OC特有)
nil 相当于C语言中的null 就是 0;
基本语句 循环,条件与C一致
注释 与C一致
屏幕输出 OC中为NSLog 不是printf NSLog(@"Hello world") NSLog(@"%i", 27)
4、OC开发编译流程 文件名.m(源文件) --编译(生成二进制文件)--> 文件名.o (目标文件) --链接--> a.out (可执行文件)
C开发编译流程 文件名.c(源文件) --编译(生成二进制文件)--> 文件名.o (目标文件) --链接(将OC函数库打包在一起)--> a.out (可执行文件)
两者之间的区别主要在于: 1、源文件是不同类型的;
2、在链接时,OC不会将函数一起打包到可执行文件中;但是C语言会将函数一起打包
3、在OC链接的时候需要主动告诉编译器引用的头文件
如 编译 cc -c firstOC.c 链接: cc firstOC -framework Foundation 执行:./a.out
其中程序中用到了Foundation框架中的函数,所以在链接时需要指定框架,这也是与C不同的地方。
.mm 的文件可以编写 C C++ OC
5、第一个OC程序
NSLog 输出内容会自动换行
#import 的用途
1)、跟#include 一样,拷贝文件的内容。
2)、可以自动防止文件内容被重复拷贝,省去了在C语言中声明头文件时必须要用的预处理指令
#ifndef ABC
#define ABC
coding....
#endif
#import <Foundation/NSObjCRutime.h> 引用Foundation框架中的NSObjCRutime 头文件
Foundation 是框架的意思
查看框架头文件源码:
首先找到Xcode的应用程序,然后打开包,(下面的平台是iPhoneOS6.1.sdk平台的框架头文件)
/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk/System/Library/Frameworks/Foundation.framework
框架中主要的UIKit.framework、QuartzCore.framework 其中Foundation.framework 框架是基础
每个框架都有自己的主头文件.主头文件是最主要的头文件,切主头文件的名与框架相同。引用主头文件就能使用框架下的所有文件。
6、OC中的BOOL类型
BOOL类型本质:typedef signed char BOOL;
BOOL类型变量2种取值 YES NO
系统通过宏定义,并强转 YES 即为 1 NO 即为 0
#define YES (BOOL) 1
#define NO (BOOL) 0
BOOL类型输出(当作整数来用) NSLog(@"%d", YES/NO);
注意需要全部大写 BOOL b = YES;
7、面向对象AND面向过程
面向过程关注的是解决问题需要那些步骤,面向对象关注的是解决问题需要那些对象。
8、类和对象
类名第一个字母必须大写,不能有下划线,多个英文单词,用驼峰标识
9、OC程序编写实例一:
类的声明(用来声明对象的属性)
@interface Animal : NSObject
{
//@public 可以让外部的指针间接访问对象内部的成员变量,后面的所有变量都可以访问,不需要一一的添加@public
@public
int age; //定义的成员变量,系统默认初始值为0;
}
/*
OC方法的声明不不需要被{}括住,所以注意变量和方法声明时的位置
方法(行为): 方法名、参数、返回值(声明、实现)
只要是OC对象的方法,必须以减号 - 开头
OC方法中任何数据类型都必须用小括号() 扩住
OC方法中的小括号() : 括住数据类型
*/
- (void) run; //正确方式
- void run(); //错误的
定义带参数的切返回double类型方法(OC方法中一个参数对应一个冒号,切括号只能括数据类型)
- (double) fangfa :(int) a;
- (int)fangfa:(int)a :(int)b;
[jsp fangfa:10 :5]; 注意添加空格
@end //表示类声明结束
// : NSObject目的是 让Animal这个类具备创建对象的能力 (NSObject 父类,存放在Foundation框架中)
类的实现(用来实现@interfac中声明的方法)
@implementation Animal
//注意实现方法时,外层不需要{}括住了。
//方法的实现
- (void) run
{
NSLog(@"动物都会奔跑");
}
@end //类的实现结束
int main()
{
/*
在OC中,想执行一些行为,就写上一个中括号 [行为执行者(对象) 行为名称(方法)]
利用类来创建对象
执行Animal这个类的new行为(方法)来创建新对象
*/
[Animal new];
/*
定义一个指针p,p将来指向的是Animal类型的对象
[Animal new] 会创建出一个新对象,并且会返回新对象本身(新对象的地址)
*/
Animal *p = [Animal new];
/*
给p所指向对象的age属性赋值。赋值方式为结构体的形式
*/
p->age = 19;
/*
给p指向的对象发送一个run消息,即通过对象p调用run方法执行
*/
[p run];
return 0;
}
/**
OC中想修改对象、操作对象只能用指针
OC对象的本质就是结构体
**/
10、OC程序编写实例二:
@interface Person : NSObject
{
@public
int age;
int weight;
}
- (void) walk;
@end
@implementation Person
- (void) walk
{
/*
对象调用时,访问的方法可以直接使用他内部的变量。
(对象在创建时,对象自身内存会包含方法、对象,所以当对象调用方法时,方法是可以直接使用对象内部的变量的)
*/
NSLog(@"%i岁的人,%f斤,正在走路", age, weight);
}
@end
int main()
{
/*
在使用类创建对象之前,会将类加载进内存中,切只加载一次,被对象之间公用。
每个对象本身都带有一个isa指针,通过这个指针就可以找对所属的类
*/
Person *p = [Person new];
p->age = 20;
p->weight = 50.5;
[p walk];
return 0;
}
11、常见错误:
@interface 与 @implementation 之间不能嵌套
方法的实现不能写在@interface中。
在定义的@interface 与 @implementation之间不能嵌套任何东西
@interface
@end
@implementation
@end
在@interface中声明成员变量(实例变量) 不允许在这里初始化
在@interface中声明成员变量(实例变量) 不能随便将成员变量当作C语言中的变量来使用,比如加个static修饰之类的动作
@interface需要放在被调用的前边,具体实现可以放在后面。就是需要先在内存中定义了,才能调用。
12、OC的方法和函数区别
(在参数传递时,形参会在使用时,在系统中创建临时的内存空间)
OC的方法必须在@interface @end中声明在@imlementation @end中定义; 对象方法归类、对象所有
函数则不需要,函数可以写在文件中的任何地方(@interface @end 之间除外),函数归文件所有。
@imlementation Person
- (void) fangfa //OC方法
{
hanshu(); //在方法中调用函数
}
void hanshu(); //OC函数
@end
对象方法都是以减号 - 开头
对象方法只能由对象调用,需要实例对象
函数不能直接访问在@interface @end中定义的实例变量
函数不依赖对象
13、OC程序练习
#import <Foundation/Foundation.h>
typedef enum{
SexMan, //注意枚举中的可以选择的数据,所有用逗号分隔.
SexWoman
} Sex;
//注意枚举和结构体中的区别
typedef struct {
int year;
int month;
int day;
} Date;
@interface Dog : NSObject
{
@public
int weighe;
}
- (void) eat;
@end
@implementation Dog
- (void) eat
{
NSLog(@"通过学生方法调用dog的吃方法");
}
@end
@interface Student: NSObject
{
@public
char *name;
int age;
Sex sex; //性别只有男女,所以定义为枚举类型,只取这两个数值就好
Date birthday; //生日,定义成结构体
Dog *d; //重点在学生对象中包括狗的对象 为指针
}
- (void) stady;
- (void) feedDog;
@end
@implementation Student
- (void) stady
{
NSLog(@"%s同学,性别%d,%i岁, 出生于 %d-%d-%d", name,sex,age,birthday.year,birthday.month,birthday.day);
//注意这里在使用结构体中的数据时不能用 ->
}
- (void) feedDog
{
[d eat]; // 调用狗的吃方法
}
@end
int main()
{
Student *s = [Student new];
s->name = "Tom";
s->age = 23;
s->sex = SexMan;
s->birthday.year = 2011;
// s.birthday.month = 02; //这样 调用是不对的
s->birthday.month = 02;
s->birthday.day = 20;
// s->birthday->day = 25; //错误
[s stady];
/*上面的时对学生进行操作,下面通过学生来让狗吃东西*/
//创建狗的实例给学生中的指针
Dog *d = [Dog new];
d->weighe = 20;
s->dog = d;
[s feedDog];
return 0;
}
14、OC方法名
- (double) pi;
//方法名 pi
- (int) test:(int)num;
//方法名 test: (OC中冒号也是方法名的一部分)
- (int) sumWithNum1:(int)num1 andNum2:(int) num2;
//方法名 sumWithNum1:andNum2:
15、@interface @end @implementation @end 是成对出现的哦
16、比较两个车的速度,分别用函数和方法
#import <Foundation/Foundation.h>
@interface Car : NSObject
{
@public
int speed;
}
- (int) compareSpeed:(Car *) c1;
@end
@implementation Car
- (int) compareSpeed:(Car *) c1
{
return speed - c1->speed;
}
@end
int compare(Car *c1,Car *c2);
int main()
{
Car *c = [Car new];
c->speed = 90;
Car *c1 = [Car new];
c1->speed = 80;
int result = compare(c,c1);
int s = [c compareSpeed:c1];
NSLog(@"%i",s);
return 0;
}
int compare(Car *c1,Car *c2)
{
if (c1->speed > c2->speed) {
return 1;
}
return 0;
}
17、匿名对象
Car *c = [Car new]; c->speed = 2500; [c run]; //正常标准的写法,使用匿名对象的方式会有内存泄漏的危险不建议
@interface Car : NSObject
{
int speed;
}
- (void) run;
@end
@implenentation Car
- (void) run
{
NSLog(@"%i",speed);
}
@end
1)[Car new]->speed = 300; //[Car new] 就是匿名对象,没有把对象给出实际的名称
2)[[Car new] run]; 使用匿名对象调用方法
第一句虽然给speed赋值为300,但是第二句执行结果输出为 0 。因为[Car new] 又会新建一个对象。