【Objective-C 篇】 ☞ 1. 基础、语法

1. 第一个OC程序

框架(Framework)

CHello不同:

1) 扩展名(后缀名).m

2) 使用Foundation框架

3) 使用#import导入头文件:

#import <Foundation/Foundation.h>

#import 会自动处理头文件重复导入问题

4) 使用NSLog函数输出日志信息

5) 使用clang编译器,并且连接Foundation框架:

clang -framework Foundation xxxx.m (编译时要注意指定Foundation框架)

 

Unix/Linux/苹果系统下可执行文件的后缀名可以是任何文件,可以是任意后缀名或没有后缀。

如,a.out==a.txt (都可以执行!)

总结一个文件扩展名(后缀名):

.c ===C语言源程序文件

.m ===OC

.cpp ===C++

.cc ===》某些Unix系统的C++

.mm ===Objective C++

 

.s ===》汇编

.i ===》经过预处理后的源程序

.o ===》编译还没连接的二进制文件

.o.out cc++Objective-C语言编译后生成的文件)

 

.a ===》静态库文件

.so ===Unix/Linux下的动态库文件

.dylib ===Mac OS/iOS 动态库文件

2. 编译器

C语言标准编译器是: gcc   OC早期的编译器使用gcc  gcc不是苹果公司的)

OC现在的编译器:

clang (苹果公司自己开发的,独立的编译器)

LLVM(小的一个语言虚拟机)集成在Xcode中【特点:随时编译,方便Xcode自动随时检查语法错误】

C语言编译器:gcc

OC语言的编译器:clang (由于OC语言兼容所有的C语言语法,所以也可以用clang编译器编译C程序)

3. Xcode写OC程序

  

  只需要在C语言字符串前面加上@符号, 系统就会自动将C语言字符串转换为OC字符串。

4. 面向对象编程

4.0 定义

面向对象编程: 直接使用解决现实生活中问题的办法来解决计算机问题。

4.1 对象

Anything is Object 万物皆对象,现实中,对象是一种客观上的存在。

程序中对象是一片内存空间,这片空间中存放表示对象的数据。

对象:类这种类型的变量

对象中有:

有什么      属性

能干什么   方法

 

4.1.1 系统中的对象:

一个对象有可能由若干个小对象组成

对象职能单一,一个对象只做自己该做的事

对象们各司其职,各尽所能

对象与对象之间有一定联系,之间用发消息的方式进行工作

这些对象构建成一个运行的系统。

 

4.1.2 %@打印一个对象(实例对象/类对象):

只要利用%@打印某个对象, 系统内部默认就会调用父类的description方法

打印对象的本质是:打印description方法中的字符串!

    

4.1.3 匿名对象

有名字的对象:只要用一个指针保存了某个对象的地址, 我们就可以称这个指针为某个对象(称p为TRPerson的对象)

TRPerson *p = [TRPerson new];

p.name = @"张三";

p.age = 22;

[p show];

没有名字的对象

无论有没有名字, 只要调用new方法都会返回对象的地址

每次new都会新开辟一块存储空间

[TRPerson new].name = @"张三";

[TRPerson new].age = 22;

[[TRPerson new] show];

4.2

类是类型的意思,现实中是一种主观的认识

在计算机中,类是自定义类型,是创建对象的模型(模板)

类就是用于描述对象的共性特征,主要用于描述对象的属性和行为

类中有:属性的定义和方法的定义

4.2.1 类的本质:类其实也是一个对象(类对象),这个对象会在这个类第一次被使用的时候创建。

  • 只要有了类对象, 将来就可以通过类对象来创建实例对象
  • 实例对象中有一个isa指针, 指向创建自己的类对象
  • 类对象中保存了当前对象所有的对象方法
  • 当给一个实例对象发送消息的时候,会根据实例对象中的isa指针去对应的类对象中查找

类对象代表类,class类型,对象方法属于类对象

如果消息的接收者是类名,则类名代表类对象

所有类的实例都由类对象生成,类对象会把实例的isa的值修改成自己的地址,每个实例的isa都指向该实例的类对象。

 

4.2.2 如何获取类对象?

Class c = [类名/实例对象 class];

 

类对象的应用场景:

  • 用于创建实例对象

TRPerson *p3 = [c1 new];

TRPerson *p4 = [[c3 alloc]init];

  • 用于调用类方法

[c3 method];//等价于[TRPerson method];

 

4.2.3 类的启动过程(系统内部自动调用的两个方法:load方法 initialize方法)

  • load方法:程序一启动就会调用
    • 只要程序启动就会将所有类的代码加载到内存中, 放到代码区
    • load方法会在当前类被加载到内存的时候调用, 有且仅会调用一次
    • 如果存在继承关系, 会先调用父类的load方法, 再调用子类的load方法
  • initialize方法:
    • 当类第一次被使用的时候就会调用(创建类对象的时候)
    • initialize方法在整个程序的运行过程中只会被调用一次, 无论你使用多少次这个类都只会调用一次
    • initialize用于对某一个类进行一次性的初始化
    • initializeload一样, 如果存在继承关系, 会先调用父类的initialize再调用子类的initialize

   

4.3 OC中定义类和创建对象

4.3.1 定义一个类

分两部分:接口部分,实现部分

1、接口部分

声明类的目的: 告诉系统我们这个类中有哪些属性和方法

@interface  类名 : 父类名   //类开始

//定义属性

//声明方法(相当于声明函数)

@end   //类结束

2. 实现部分

@implementation 类名

//方法的定义(相当于定义函数)

@end

 

4.3.2 创建对象

创建对象使用alloc,创建好后用一个指针将对象的地址保存起来,以便后面使用。我们把保存对象地址的指针叫引用(Reference)

类名 *引用名 = [类名 alloc];

通过类创建对象

1) 开辟存储空间,通过alloc(new)方法创建对象会在堆内存中开辟一块存储空间

2) 初始化所有属性

3) 返回指针地址

创建对象的时候返回的地址其实就是类的第0个属性的地址

但是需要注意的是: 类的第0个属性并不是我们编写的第一个属性,而是一个叫做isa的属性isa是一个指针, 8个字节

isa属性是系统内部自动帮我们添加的,当你创建一个对象的时候,系统自动生成isa属性

isa是一个指针,占8个字节

isa的作用:会指向创建这个类的那个类

     

其实类也是一个对象,也就意味着MyClass也是一个对象(类对象)

     平时我们所说的创建对象其实就是通过一个 类对象 来创建一个 新的实例对象

     类对象是系统自动帮我们创建的,里面保存了当前对象的所有方法

     而实例对象是程序自己手动通过alloc(new)来创建的,而实例对象中有一个isa指针就指向了创建它的那个类对象

 

4.3.2 对象的存储细节

类创建对象,每个对象在内存中都占据一定的存储空间,每个对象都有一份属于自己的单独的成员变量,所有的对象共用类的成员方法。

方法在整个内存中只有一份,类本身在内存中占据一份存储空间。

OC中对象创建

TRPerson *p = [TRPerson new];// 等价于 TRPerson *p = [[TRPerson alloc]init];

怎么理解这句话:

理解1:定义了一个TRPerson类型的指针变量,指针变量指向新申请的内存空间

理解2:用TRPerson类实例化了(创建了)一个实例对象,对象的名称是p

这里的new做了三件事:

  1. 向计算机申请内存空间
  2. 给类中的每一个成员赋初值
  3. 返回新申请的空间的首地址

    

  

    

4.4 定义属性

1) 在接口部分定义属性:

@property int x;

@property double y;

@property NSString *name; //对象只能通过引用访问,所以要加*(指针类型)

//NSStringOC中的字符串类型,*name代表一个指针,OC语言中字符串类型是一个对象,只能用一个指针来保存一个对象的地址,而不能直接保存一个对象;所有的对象都一样,不能直接用变量来保存对象,只能用一个指针来保存对象的地址!MyClass *obj = [MyClass alloc];

@property NSString *name;//姓名

@property int age;//年龄

@property BOOL gender;//性别

@property double salary;//工资

 

2) 访问对象中的属性:

引用.属性 = 值;

NSLog(@"%d", 引用.属性);

// %@打印字符串对象

NSLog(@“姓名: %@,性别: %@“, self.name,self.gender?@"":@"");

 

4.5 声明和定义方法

1) 在接口部分声明方法

- (返回值类型)方法名;   

- (返回值类型)方法名:参数表;

2) 在实现部分定义方法

- (返回值类型)方法名 {

//写具体的实现代码 

}

//OC中方法名会被分解成若干个部分分散在多个参数的前面。

//此方法的方法名是:"setName: age: gender: salary:"

- (void)setName:(NSString *)name

            age:(int)age

          gender:(BOOL)gender

          salary:(double)salary;

3) 调用

通过对象来调用方法

[引用 消息]; //向引用指向的对象发消息(消息的名字应该是方法名),如果引用指向的对象有和这个消息名字相同的方法,就会自动调用此方法。如果没有这个方法,程序崩溃。

4.6 实际开发中类的写法

实际开发中,类的接口部分和实现部分是分开的,接口部分放在头文件中,实现部分放在.m文件中

类名加前缀,防止命名冲突(苹果官方的前缀是两个字母,为了不与官方的重复,开发者一般用3个字母的前缀)

5. 方法(Method)

5.1 概念

本质是函数,在OC中写法和函数不同。

在方法中可以访问属性。

当一个对象收到一个消息时,调用对应的方法。

5.2 分类:

实例方法(instance method): -

类方法(class method): +

.h中声明的所有方法作用域都是public类型,不能更改。

5.3 实例方法(instance method)

实例(instance)指的是对象。一个类的对象可以被称为这个类的一个实例。

必须通过对象来调用的方法叫实例方法。具体的来说是通过指向对象的引用来调用。

5.4 实例方法的参数

无参、一个参数、多个参数

5.5 方法的返回值

和函数一样

输出一个对象详细信息的两种方法:

     

5.6 函数和方法的区别

1) 函数属于整个文件, 方法属于某一个类,方法如果离开类就不行

2) 函数可以直接调用, 方法必须用对象或者类来调用

3) 不能把函数当做方法来调用, 也不能把方法当做函数来调用

6. 成员变量、实例变量(instance variable)

6.1 概念

实例就是对象

每个对象(实例)都有一份自己独特的数据和别的对象不同,这些独特的数据会保存在对象的一些特殊变量中,这些变量就是实例变量。

每一个实例都有一份独特的实例变量。实例变量用来记录和保存数据!

 

有人也叫成员变量

C++  member variable  成员变量

member function  成员函数

6.2 定义成员变量(在OC里也叫实例变量)

//在大括号中声明的变量都为成员变量

{

    UIButton *_button;

    int age;

    id data;

}

 

成员变量的常用作用域有3种:

  1. @public 全局都可以访问
  2. @protected 只能在类内部和子类中访问
  3. @private 只能在类内部访问

6.3 实例变量和属性的关系

属性的本质:两方法(settergetter+ 实例变量

当我们在类中定义一个属性时,编译器会生成以下内容:

1) 保存属性值的实例变量,名字为"_属性名"

2) 修改实例变量值的setter方法,名字为"set属性名",并且属性名的首字母大写

3) 读取实例变量值的getter方法,名字为"属性名"

比如,定义的属性名叫name,生成的实例变量名为"_name",生成的setter方法的名字为:"setName:",生成的getter方法的名字为:"name"

 

怎么访问实例变量?

在实例方法内(类内部),可以直接访问实例变量。(如:_age=22;

在实例方法外(类外部),用以下两种方式访问:

    1)用->直接进行访问;

如:f->_name = @“张三”;  f->_age = 20; 一般不用!

如果使用,要用@public公开实例变量(实例变量默认是受保护的:@protect),才能用->访问

    2)用方法间接访问(setter/getter),属性是访问实例变量的一种方式。

setter方法可以给实例变量赋值,getter方法可以获取实例变量的值。)

 

6.4 实际开发中的经验:

一般情况下,很少会定义实例变量,而会大量的定义属性。

在头文件中,尽量不要定义实例变量,而是定义属性。

 

OC中的实例变量相当于java中的成员变量,OC中经常用实例变量来存数据。

 

有时候我们会在.m文件中定义实例变量,保存一些私有的数据。也就是说在implementation中定义。

.h文件中的是公开的,.m文件是私有的:

.h文件中定义的属性(实例变量)是公开的,在.m文件中定义的属性(实例变量)是私有的。

.h文件中声明和在.m文件中实现的方法是公开的,只在.m文件中实现,未在.h文件声明的方法是私有的。

原文地址:https://www.cnblogs.com/bossren/p/6425135.html