黑马程序员————OC基础学习重要小知识点总结

时间:2022-06-10 11:59:36

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


黑马程序员————OC基础学习重要小知识点总结


1、首先,什么是Objective-C?


    Objective-C是一门基于C语言的面向对象语言,C语言的基础上,增加了一层最小的面向对象语法,完全兼容c语言,它在现代计算机的主要作用于Mac OS X作为桌面语言以及作用于iPhone OS(亦称:iOS)。它原是NeXTSTEP 操作系统的主要语言,NeXTSTEP OS随后被苹果公司收购,并派生出Mac OS X,所以这可以很好地说明今天的苹果操作系统和它有异曲同工之妙。

    由于Objective-C是C语言的一个严格超集,所以我们可以在Objective-C文件里*地使用C语言并会顺利编译通过。因为任何Objective-C的编译器会将C代码编译过去,也就是说,我们拥有通过Objective-C实现C的面向对象能力。

那也就是说C能做的,Objective-C都能做,但反过来不成立。

苹果公司把Mac操作系统上的整个开发环境命名为Cocoa,在Cocoa上,开发语言是 Objective-C,开发工具是Xcode等。苹果公司专门提供了iPhone/iPad软件开发包,这个开发包提供了很多框架(Framework),从而帮助开发人员快速地开发应用程序。


2、学习OC必须要有一定的C的基础,那是因为:

1) OC基于C
2) OC跟C的思想和语法很多地方不太一样,而且OC能和C混用
3) C是所有编程语言中的经典,很多高级语言都是从C语言中衍生出来的,比如C++、C#、Objective-C等

C程序的运行过程主要分为以下几个部分:

黑马程序员————OC基础学习重要小知识点总结

黑马程序员————OC基础学习重要小知识点总结


编译:

1)         什么是编译:将C源程序翻译成计算机能识别的0和1

2)         使用什么编译器:Xcode3使用GCC,Xcode4使用LLVM编译器(前端用clang)

3)         如何使用clang编译器编译程序?

  在终端中输入:cc  –c  文件名.c

  编译成功,会生成.o目标文件

4)         编译器的错误和警告功能

 如果代码有语法问题,编译器会直接报错。并指出错误的个数和具体行号。

  只要有1个错误,程序就不能编译成功,也不会生成.o文件

  警告信息只是编译器的一些建议,并不影响编译通过


链接:

1)         链接的作用:将.o文件和C语言函数库组合在一起,生成可执行文件

2)         由链接器完成,clang编译器里面已经包含了链接指令

 在终端中输入:cc  文件名.o

  链接成功,会生成a.out可执行文件


运行:

1)         两种运行方式

     直接双击打开a.out文件

     终端中使用 ./a.out指令

2)         修改文件内容之后,一定要重新编译、链接,再运行

3)         \n的作用:回车换行


C程序编写执行过程:

1、  编写代码

2、  编译:把C语言代码翻译成0和1

工具:clang 编译器(Xcode3 gcc  Xcode4 LLVM(clang))

安装命令行工具

指令:cc  -c 文件名.c  (compile)

编译成功,会生成一个.o目标文件

3、  链接:其实就是把.o目标文件跟系统自带的函数库合并在一起,生成一个可执行文件

链接器

指令:cc 文件名.o   

 

4、  运行

a.out,生成a.out 文件,打开方式两种,一种是./ a.out 回车,另一种是双击执行就可以了

-o  文件名就可以改文件名,改a.out 改为其他名字


  总结常见文件的拓展名

  .c是C语言源文件,在编写代码的时候创建

 .o是目标文件,在编译成功的时候产生

 .out是可执行文件,在链接成功的时候产生

  .h是头文件,头文件包含类、类型、函数和常量声明

  .m实现文件。具有此扩展名的文件可以同时包含OC代码和c代码,有时也称源文件

  .mm实现文件。具有此拓展名的实现文件,除了包含OC代码和c代码以外,还可以包含C++代码,仅当实际引用OC代码中的C++类或功能时,才使用此拓展名

2)         总结clang指令

  编译:cc  –c xxx.c

  链接:cc  xxx.o

 编译、链接:cc  xxx.c

运行可执行文件:./a.out 


3、对于Mac系统与Windows系统的一些常用习惯的区别:

Mac常用快捷键:

文件操作

复制:Command + C  

 粘贴:Command + V

 回退:Command + Z

 保存:Command + S

窗口操作

关闭窗口:Command + W

 退出程序:Command + Q

 管理多个桌面:Ctrl + ↑

 切换程序窗口:Command(长按) + tab

 切换输入法:Command(长按) + 空格


Mac的文件系统:

 Mac系统采用的是UNIX文件系统,所有的文件都放在根目录/下面,因此没有Windows中分C盘、D盘的概念,文件路径就不再有盘符

Windows中  c:/users/mj/desktop

 Mac中      /users/mj/desktop

 常见文件夹

用户的个人文件夹(apple是用户名):/Users/apple

桌面:/Users/apple/Desktop

 文稿:/Users/apple/Documents

 下载:/Users/apple/Downloads

应用程序:/Users/apple/Applications


常见Unix指令:

因为Mac系统是基于UNIX系统的,因此可以在“终端”中输入一些UNIX指令来操作Mac系统。比如:新建文件\文件夹、打开文件\文件夹

常用的UNIX指令:(需要经常使用才不容易忘记)

ls –l 列出当前目录下的所有内容(文件\文件夹)

 pwd             显示出当前目录的名称

 cd                 改变当前操作的目录

 who             显示当前用户名

 clear            清屏

 mkdir           新建一个目录

 touch           新建一个文件(文件不存在才会新建)

 open            打开一个文件\文件夹

按一下tab键,可以自动补齐指令名称、文件名、文件夹名等

(上述指令均可以在百度上搜索到具体用法)

Unix指令中的特殊路径:

在使用Unix指令过程中,经常会涉及到目录(路径)操作,下面列出几个有特殊含义的路径:

 /   根路径

 ./  当前路径

 ../ 上一级路径


4、关于C的一些小细节:


返回值:

Return的作用:

1、  退出函数

2、  返回一个具体值给函数调用者

Void:

没有返回值

返回值注意点:

1、  void代表没有返回值

2、  如果不声明返回值类型,默认就是int 类型。

3、  就算明确声明了返回值类型,也可以不返回任何值。


默认情况下,C语言不允许两个函数的名字一样

 

函数注意点:

1、  默认情况下,不允许函数名称一样

2、  函数不能嵌套定义

3、  函数不能重复定义,但是可以重复声明

4、  如果有函数的声明,没有函数的定义

函数编译可以通过,因为编译器只会检测语法合不理,并不会检测函数有没有定义

链接会报错,因为链接的时候会检测函数是否定义

include 作用:

1、  拷贝右边文件夹的所有内容到#include所在的位置。

2、  自定义的文件用””,系统自带的文件用<>

3、  #include<stdio.h>的目的:拷贝printf函数的声明


import 的用途:

(1)跟#include一样,拷贝文件的内容

(2)可以自动防止文件的内容被重复拷贝


函数的定义放.c文件,函数的声明放.h文件

如果要使用某个.c文件中定义的函数,只需要#include这个.c文件对应的.h文件

.h文件的作用:被别人拷贝,编译链接的时候不要管.h文件

 

 数组作为函数参数,可以省略元素个数

数组作为函数参数,传递是整个数组的地址,修改函数形参数组元素的值,会影响到外面的实参数组。

 

数组当做函数参数传递时,会当做指针变量来使用,指针变量在64bit编译器环境下,占据8个字节

 


%d: int

%f:float/double

%ld:long

%lld:long long

%c:char

%s:字符串

%zd:unsigned long



5、关于OC的细节总结:

OC程序的开发过程:
 
终端指令:  
                 
编译cc –c main.m
链接cc main.o       –framework Foundation
运行./a.out


NSLog与printf的区别:
NSLog接收OC字符串作为参数,printf接收C语言字符串作为参数
NSLog输出后会自动换行,printf输出后不会自动换行
使用NSLog需要#import <Foundation/Foundation.h>
使用printf需要#include <stdio.h>




1、import 的用途:

(1)跟#include一样,拷贝文件的内容
(2)可以自动防止文件的内容被重复拷贝


2、#import<Foundtion/NSObjCRuntime.h>
NSObjCRuntime.h中有NSLog函数的声明


3、主头文件:
(1)主头文件:最主要的头文件,名字一般跟框架名称一样,包含了框架中所有的其他头文件
(2)Foundation框架的主头文件名称就是Foundation.h
(3)只需要包含Foundation框架的主头文件,就可以使用整个框架的东西


4、运行过程:
(1)编写OC源程序:.m 、 .c
(2)编译:cc  -c  xxx.m  xxx.c
(3)链接: cc xxx.o  xxx.o  -framework Foundation
(只有用到了Foundation框架才需要加上-framework Foundation)
(4)运行: ./a.out


面向对象与面向过程的区别:
1、以电脑听歌为例:
(1)面向过程:
打开电脑    播放电脑的歌曲  关闭电脑
(2)面向对象:
电脑  (开机   播放歌曲  关机  )


区别分析:
面向过程关注的是解决问题需要哪些步骤,面向对象关注的是解决问题需要哪些对象


现实生活中面向对象的例子:
想打电话\发短信  找手机,不用分析电话要怎样才能拨通
去饭店吃饭  找服务员,不用分析怎么到厨房炒菜
汽车坏了  找汽车维修工,不用分析修车的步骤
境界:万物皆对象


类和对象的关系:
1) 现实生活的例子:如何创造汽车对象?
a) 需要先有汽车的建造图纸,图纸上描述清楚汽车应该具备的属性和功能(行为)
属性:*数、时速
功能(行为):跑
b) 然后再根据图纸上的描述生成汽车
c) 每一辆汽车都是对象,都有自己具体的属性值,都是图纸的实例
d) 图纸是抽象的,房子是具体的。图纸是对房子对象的高度概括


1. OC中的面相对象
1) OC中的类相当于图纸,用来描述一类事物。也就是说,要想创建对象,必须先有类
2) OC利用类来创建对象,对象是类的具体存在
3) 因此,面向对象解决问题应该是先考虑需要设计哪些类,再利用类创建多少个对象


2. 需要设计哪些类,如何设计类
1) 类的设计,只关心3样东西:
事物名称(类名):人(Person)
属性:身高(height)、年龄(age)
行为(功能):跑(run)、打架(fight)
2) 一般名词都是类
坦克发射3颗炮弹轰掉了2架飞机
小明在公车上牵着一条叼着热狗的狗
3) 拥有相同(或者类似)属性和行为的对象都可以抽像出一个类


类的设计:
1、 类名
(类名的第一个字母必须大写,不能有下划线,多个英文单词,用驼峰标识)
2、 属性
3、 行为(功能)


植物大战僵尸的僵尸:
1、 僵尸
类名:JumpZoobie
属性:life、speed、 gongjili  
行为:walk、 bite、die 


雷电的飞机:
类名:Plane
属性:life、gongjili、speed、bombCount
行为:fly、bomb、shoot、die

常用术语
面向过程 ProcedureOriented
面向对象 ObjectOriented,简称OO
面向对象编程 ObjectOriented Programming,简称OOP

5、定义OC的类和创建OC对象:


类的声明
1) 代码编写
定义一个Car类,拥有2个属性:*数、时速,1个行为:跑
类名\属性的命名规则:标示符的规则
类名的命名规范:有意义、驼峰标识、首字母大写

#import <Foundation/Foundation.h>
// 类的声明
@interface Car : NSObject
{
@public
int wheels; // 多少个*
int speed; // 时速
}
- (void)run; // 跑的行为
@end


2)成员变量
@interface的大括号{}中声明的变量:wheels、speed
@interface的大括号和函数的大括号是不一样的
默认会初始化为0


3)@public
@public可以让Car对象的wheels和speed属性被外界访问


4)NSObject
加上:NSObject的目的是让Car类具备创建对象的能力


类的实现


// 类的实现
@implementation Car
- (void) run
{
NSLog(@"%i个*,%i时速的车子跑起来了", wheels, speed);
}
@end

创建对象
1) 代码编写

// 主函数
int main()
{
// 创建车子对象
Car *c = [Car new];
c->wheels = 3;
c->speed = 300;

[c run];
return 0;
}

2) main函数的代码分析、内存分析(对象在内存中有成员)
[Car new]每次都会创建出新的对象,并且返回对象的地址,那么就应该用一个指针变量保存对象的地址
Car *c = [Car new];
用一个指针变量c指向内存中的Car对象
设置车子对象的属性
跟用指向结构体的指针访问结构体属性一样,用->
c->wheels = 3;
c->speed = 300;


创建多个Car对象

分别只设置wheels、speed属性
Car *c1 = [Car new];
c1->wheels = 4;
Car *c2 = [Car new];
c2->speed = 250;
[c1 run];
1个赋值给另一个,然后修改属性
Car *c1 = [Car new];
c1->wheels = 4;
c1->speed = 250;
Car *c2 = c1;
c2->wheels = 3;
[c1 run];

面向对象封装的好处
更加接近人类的思考方式
只需要关注对象,不需要关注步骤


对象与函数参数

对象成员变量作为函数参数
指向对象的指针作为函数参数
修改指向指向对象的成员
修改指针的指向

@interface就好像暴露在外面的时钟表面
@implementation就好像隐藏在时钟内部的构造实现


OC方法和函数的区别
OC方法只能声明在@interface和@end之间,只能实现在@implementation和@end之间。也就是说OC方法不能独立于类存在
C函数不属于类,跟类没有联系,C函数只归定义函数的文件所有
C函数不能访问OC对象的成员
低级错误:方法有声明,但是实现的时候写成了函数


OC的方法注意
方法只有声明,没有实现(经典错误)
方法没有声明,只有实现(编译器警告,但是能调用,OC的弱语法)
编译的时候:访问没有的成员变量直接报错,访问没有的方法,只是警告


@implementation
没有@interface,只有@implementation,也是能成功定义一个类的
@implementation Car : NSObject
{
    @public
    int wheels; // 多少个*
    int speed; // 时速
}
- (void) run
{
    NSLog(@"%i个*,%i时速的车子跑起来了", wheels, speed);
}
@end
@implementation中不能声明和@interface一样的成员变量


       方法:

不带参数的方法:

      黑马程序员————OC基础学习重要小知识点总结



方法调用:黑马程序员————OC基础学习重要小知识点总结


黑马程序员————OC基础学习重要小知识点总结


带一个参数的方法:

黑马程序员————OC基础学习重要小知识点总结

黑马程序员————OC基础学习重要小知识点总结

黑马程序员————OC基础学习重要小知识点总结

  方法调用:

黑马程序员————OC基础学习重要小知识点总结


黑马程序员————OC基础学习重要小知识点总结

带多个参数的方法:


黑马程序员————OC基础学习重要小知识点总结

黑马程序员————OC基础学习重要小知识点总结

方法调用:


黑马程序员————OC基础学习重要小知识点总结

黑马程序员————OC基础学习重要小知识点总结

方法名注意
冒号也是方法名的一部分
同一个类中不允许两个对象方法同名


一个小例子的引入:

例:

/*
类名:Car
属性:轮胎个数、时速(速度)
行为:跑
*/
//完整地写一个函数:函数的声明和定义(实现)
//完整地写一个类:类的声明和定义
//因为使用了NSObject
#import <Foundation/Foundation.h>
//类的声明
//声明对象的属性、行为
// : NSObject 目的是:让Car这个类具备创建对象的能力
@interface Car : NSObject
{//用来声明对象属性(实例变量\成员变量,默认初始化为0)1
//@public可以让外部的指针直接访问对象的内部的成员变量
@public
int wheels;//轮胎个数
int speed;//时速(xxkm/h)
}
//方法(行为):方法名、参数、返回值(声明、实现)
//只要是OC对象的方法,必须以减号-开头
//OC方法中任何数据类型都必须用小括号()扩住
-(void) run; //OC方法中的小括号():扩住数据类型,没有数据类型不要写
@end
//类的实现
//用来实现@interface中声明的方法
@implementation Car
//方法的实现(说清楚方法里面有什么代码)
-(void)run
{
NSLog(@“车子跑起来了”);
}
@end
int main()
{
//利用类来创建对象,在OC中,想执行一些行为,就写一个中括号[行为执行者 行为名称]
//执行了Car这个类的new行为来创建对象
//定义了一个指针变量p,p将来指向的是Car类型芙蓉对象
//[Car new]会创建一个新的对象,并且返回新的对象本身(新对象的地址)
Car *p = [Car new];

Car *p2 = [Car new];

p2->wheels = 5;
p2->speed = 300;
[p2 run];
//给P所指向对象的wheels属性赋值
p->wheels = 4;
p->speed = 250;
//OC中对象只能通过指针来实现
//给p所指向对象发送一条run消息
[p run];
NSLog(@"车子有%d个*,时速为:%dkm/h",p->wheels,p2->speed);
return 0;
}