OC 基础入门
OC 源文件
OC 源文件为 .h 和 .m( m表示 message,表示 OC 中的消息机制 )
在 .m 文件中可以写 OC 代码、C 代码、C++ 代码。反正 Java 的 .class 文件不能写 C 和 C ++。
NS 前缀
从之前的 OC 的历史中知道 OC 来自 NextStep. 所以许多的 OC 的类都是带了 NS 前缀。
注释
OC 的注释和 Java 一样分为两种:
单行注释:
// 我是单行注释
多行注释
/*
*我是多行注释
*/
@符号
在 OC 中大多数的关键字是用 @ 符号开头的。并且字符串类型是以 @ 开头申明的。
main 函数
这一点是和 Java 一致,程序的入口也是 main 方法。
OC 的 main 函数是可以不带参数。写法如下:
带参
int main(int argc,const char * argv[]){NSLog(@"Hello World!");
}
不带参
int main(){NSLog(@"Hello World!");
}
Java 语言的 main 函数
public static void main(String [] args){println("Hello World!");
}
OC 基本数据结构
OC 语言包含了 C 所有的数据结构,并且有更多其他的数据结构。
C:
- int float double char
- int的修饰符
- short、long、 long long
- unsigned 、signed
- ...
OC:
- CGFloat、BOOL、NSInteger
其中 BOOL 是的取值为 YES/ON 对应就是 Java true/false.
CGFloat 和 NSInteger 是为了兼容 64 位计算机和 32 位计算机而存在的,在 32 位操作系统中,CGFloat 表示的就是 4 个字节的 float,而在 64 位操作系统中,CGFloat 表示的是 8 个字节的 double.
NSInteger 也是类似的 —— 32 位操作系统中为 4 个字节 int. 64 位操作系统中为 8 个字节 long。
OC 也是有 Boolean 存在的。Boolean 表示的值就是 TRUE/FALSE 对应就是 Java true/false
BOOL 本质:
typedef signed char BOOL;
#define YES ((BOOL)1)
#define NO ((BOOL)0)
Boolean 本质:
typedef unsigned char Boolean;
#define true 1
#define false 0
本质区别是 Boolean 定义的是枚举。BOOL 定义的是宏。
OC 的数据类型
- id 类型:万能指针,可以指向任何的 OC 对象。其实质是编译时不检测,运行时检测。
- class - 表示类
- SEL: 方法选择器
- nil:nil 类似是 NULL 但是 nil 是一个对象
- block : 表示一个代码块
OC 的语法知识其实有蛮多,以下知识基础的一部分.
目录部分:
文章目录
@ 符号
在 OC 语言中,绝大部分的关键字使用的 @ 符号开头。记住这是一个规则就好了。
字符串
在 Java 中字符串和 C 语言中字符串定义的方式是一样的。
但是在 OC 中的字符串的定义是需要添加 @ 的,在OC 中字符串类型使用的是 NSString ,相对而言添加一个 NS 前缀。
Java: "Android" "Java"
OC: @"OC" @"iOS"//比如定义一个变量
NSString *name = @"小明";
NSLog 日志输出
OC 中的日志输出对象为 NSLog.
语法:NSLog(字符串); —— 表示需要打印的日志。
Java 中的 Log 和这个对标的,但是目前还没有发现 NSLog 有和 Log 日志等级关系的定义。
//简单使用
NSLog(@"Hello world, OC");
//高级使用
NSLog(@"1+1=%d",2)
#import导入指令
“#”表示的是一个预处理指令。
这个指令的作用:将文件的内容在预编译的时候拷贝写指令的地方.
简单的原理:#import指令在包含文件的时候,底层会先判断这个文件是否被包含 如果被包含就会略过 否则才会包含.
//导入系统的相关的使用的是“<>”
#import <Foundation/Foundation.h>
//导入其他非系统的类或者头文件使用的是 ""
#import "Person.h"
类
什么是一个类
面向对象语言定义基本上都是一样,这个定义 Java 和 OC 基本上没差。
描述具有相同特征和行为事物的集合。
OC 怎么创建一个类
OC 的类通常是有两个文件,一个是 .h 文件,一个是.m 文件
.h 头文件
表示一个类的声明
语法格式:
@interface 类名 : NSObject
{
声明特征(变量)
}
-声明方法
@end
说明
- interface 在 Java 中表示的是接口的意思,但是在 OC 表示的是头文件的标识。
- @end 作为表示当前这个类声明完成。
- “ :” 表示继承的关系,和 Kotlin 有点类似。
- NSObject 和 Java 是一样的,所有的对象创建时会默认自动生产一个这样的继承关系,Java 是不需要显示出来的,但是 OC 会显示出来。
@interface Person : NSObject
{int age;NSString *name;BOOL isBoy;
}
@end
.m 实现文件
表示一个类的实现
语法定义
@implementation 类名
{
特征和变量
}
方法实现
@end
注意事项:
- 在 .m 文件中定义的变量为私有变量,在其他的类是不能调用到的。
- 在 .m 中定义的方法在 .h 文件中如果没有定义就不能被外部的类所调用。
- 如果在 .h 文件中声明了一个方法,但是在 .m 文件中没有实现这个类,可编译通过,不可以运行。
@implementation Person
{//钱肯定只有自己能够访问float money;
}
@end
与 Java 语言相比,类的定义在 OC 中显得略有麻烦。
类生成对象的方式
类生成对象在 OC 有好几种常见的方式,这里只阐述两种比较常用的方式:
//第一种:
Person *person = [Person new];
//第二种
Person *person = [[Person alloc] init];
其中 alloc 表示分配内存空间, init 表示初始化成员变量。
这两种方式完全等价。
变量
语法
在 @interface 中定义的变量是在 { } 中,并且需要在变量头部声明 @public 才可以在 .m 和作为对象调用。
在 @implementation 中定义的语法只能在 .m 中使用。
代码
.h 中:
@interface Person : NSObject
{@public // 声明这些变量可以被访问int _age;NSString *_name;BOOL _isBoy;
}
@end
.m 中:
@implementation Person
{//钱肯定只有自己可以访问了int moeny;
}
@end
调用
//这个是和 C 语言兼容过来的。
Person *person = [Person new];
person->_name = 3;
方法
调用角度分为两种:一种是类方法;一种是对象方法。
这个地方对标的是 Java 中的静态方法和类方法。
从方法本身定义出发,也是分为两种:一种是无参方法和有参方法。
和所有其他的程序语言一样。
方法的构成的要素:(与语言无关)
- 返回类型
- 方法名称
- 参数(可有可无)
无参对象方法
语法
-(返回类型)方法名称;
这个语法和 Java 的差异还是蛮大的。
方法申明:
@interface Person : NSObject
{int age;NSString *name;BOOL isBoy;
}
- (void) eat;
@end
方法实现:
@implementation Person
{//钱肯定只有自己能够访问float money;
}
@end- (void) eat{NSLog(@"人是铁饭是钢");
}
调用方法
[对象 方法名]
Java 中的都是点语法 ,但是在 OC 中不是这样。
//Java对象方法调用(Java 中不存在类对象的概念,只是为了区分所以此处表示为对象方法)Person mPerson = new Person;mPerson.eat();//OC 中对象方法调用
Person *person = [Person new] ;// OC 生成对象的方式
[person eat];
有参对象方法
语法
-(返回值类型)方法名称:(参数类型)参数名称1 : (参数类型)参数名称2
方法名称和参数数值之间以 “:” 表示分隔。
方法申明:
@interface Person : NSObject
{@public // 声明这些变量可以被访问int _age;NSString *_name;BOOL _isBoy;
}
//无参
-(void)eat;
//有参
-(void)setName:(NSString *)name withAge:(int)age withIsBoy:(BOOL)isBoy;
@end
方法实现:
@implementation Person
{//钱肯定只有自己可以访问了int moeny;
}
-(void)eat{NSLog(@"人是铁饭是钢");
}
/*setName withAge withBoy withIsBoy 这个整体就是一个方法名称,至于为*什么用 withXXX 这是 OC 书写的一种比较好的习惯吧。这些变量之间没有特殊的符号的定义,除了变量空格就好了。*/
-(void)setName:(NSString *)name withAge:(int)age withIsBoy:(BOOL)isBoy{_name = name;_age = age;_isBoy = isBoy;
}
@end
调用方式
这就不用相关的语言描述了。直接上代码:
Person *person = [Person new];
// 一个叫小明,3岁的男孩。
[person setName:@"小明" withAge:3 withIsBoy:YES];
以上基本就是对象方法的全部了
类方法
对象的方法用 “-” 表示。类方法用 “+” 表示。其他的方式全部和对象方法一致。
语法上体现的很简单。
在 OC 中类方法不能访问属性。所以一般如果在一个方法中不需要用到类属性的关系就可以使用类方法,相比而言,类方法的有:
- 节约空间:不需要生成对象就可以调用方法
- 提高效率:可以直接通过类访问方法
方法声明:
@interface Utils: NSObject//无参方法+ (void)start;//计算和(有参方法)+(int)add:(int)num1 andNum2:(int)num2;
@end
方法实现:
@implementation Utils+ (void)start{NSLog(@"开始啦....");}+ (int)add:(int)num1 andNum2:(int)num2{return num1 + num2;}
@end
方法调用:
//类方法调用无参方法
[Utils start];
//类方法调用有参方法
[Utils add: 1 andNum2: 2 ];
分组导航标记
在 OC 中有一种特殊语法,可以给相关方法分区。
Java 中可能有这样操作。但是我是不知道,XCode 中支持相关方法的预览。比如说所有的点击事件的响应可以分类为 View Action。UI 可以分为 initView。
语法规则
#pragma mark - 分组名称
如下图示说明:
效果图示
nil 与 NULL 的差异
在 Java 中 null 表示一个空对象。在 OC 中有 nil 和 NULL 两种方式,其中 NULL 属于 C 的定义。
NULL:表示这个定义没有指向任何内存的空间。
nil: 表示这个定义没有指向任何对象。
因为 OC 是面向对象的语言,所以一般建议使用 nil 来表示一个对象没有被赋值。
简单的 OC 运行时内存区域划分
| 区域 | 定义 |
|---|---|
| 堆 | 存储临时变量 |
| 栈 | 存储成员变量,通过 new 或者 alloc 申请出来的空间 |
| BSS段 | 存储未初始化的全局变量,比如静态变量 |
| 数据段 | 存储已经初始化的全局变量,比如常量 |
| 代码段 | 存储代码,存储程序的代码 |
加载类
和 Java 一样,OC 中代码也是有类加载的概念,这个对于我们来说还是蛮好理解的 ,程序没有运行时,代码是储存在物理内存中,程序运行时肯定需要一家代码的加载的过程,加载最小的单元就是类,那么加载类的过程就是加载类了。
好像写的有点啰嗦了。
类对象
在 Java 中,我查过一些资料,没有类对象的概念,这个概念应该是 OC 语言独有的概念了。
类加载完成之后就是就会生成一个类对象。类对象的生命周期和程序的生命周期都是一样的。
OC 的类对象其实是这样的,比如一个类加载成类对象以后,如果下一次去生成一个对象的时候,直接用类对象生成,不需要再去进行类加载的操作。
类对象会加载会加载方法到代码去,因为我们在操作一个实例对象的时候,是在操作他的相关变量。而其中对应的方法实现一直都是一样的,那么就不需要重复加载,浪费空间和时间。在 OC 中实例对象只会包含类对象的引用。可以去看一下运行的代码很看到一个 isA 的引用,这个就是类对象的引用。
对象生成的过程
宏观来看,OC 实例对象的生成和 Java 实例对象的初始化过程差不多,都是申请内存,然后初始化变量。
1). Person *p1; 会在栈内存中申请1块空间. 在栈内存中声明1个Person类型的指针变量p1。
p1是1个指针变量. 那么只能存储地址.
2). [Person new]; 真正在内存中创建对象的其实是这句代码.
new做的事情
A. 在堆内存中申请1块合适大小的空间.
B. 在这个空间中根据类的模板创建对象.
类模板中定义了什么属性.就把这些属性依次的声明在对象之中.
对象中还有另外1个属性 叫做isa 是1个指针. 指向对象所属的类在代码段中的地址.
C. 初始化对象的属性
如果属性的类型是基本数据类型 那么就赋值为0
如果属性的类型是C语言的指针类型 那么就赋值为NULL
如果属性的类型是OC的类指针类型 那么就赋值为nil
D. 返回对象的地址.
其中实例对象只有属性没有方法,至于原因上面已经说明白了。
属性的默认值
默认值和 Java 基本一样,如下:
- 如果属性的类型是基本数据类型 默认值是0(BOOL 是 false )
- 如果属性的类型是C指针类型 那么默认值是NULL
- 如果属性的类型是OC指针类型 那么默认值是nil







![[cuda]cuda驱动版本对应+旧版本cuda下载网址](https://img-blog.csdnimg.cn/721c4848a2444356aeca99a24a852651.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1N0cmVuZ3RoZW5ubg==,size_16,color_FFFFFF,t_70#pic_center)





![Cuda11.6 下载与安装[排坑版]](https://img-blog.csdnimg.cn/886b40da2be545e58cf2fc4040095500.png)



