OC的一些细节
对象的存储细节
通过类创建对象
1.开辟存储空间, 通过new方法创建对象会在堆 内存中开辟一块存储空间
2.初始化所有属性
3.返回指针地址
创建对象的时候返回的地址其实就是类的第0个属性的地址
但是需要注意的是: 类的第0个属性并不是我们编写的_age, 而是一个叫做isa的属性
isa是一个指针, 占8个字节
其实类也是一个对象, 也就意味着Person也是一个对象
平时我们所说的创建对象其实就是通过一个 类对象 来创建一个 新的对象
类对象是系统自动帮我们创建的, 里面保存了当前对象的所有方法
而实例对象是程序自己手动通过new来创建的, 而实例对象中有一个isa指针就指向了创建它的那个类对象
1. 对象的存储细节
- 类创建对象,每个对象在内存中都占据一定的存储空间,每个对象都有一份属于自己的单独的成员变量,
所有的对象公用类的成员方法,方法在整个内存中只有一份,类本身在内存中占据一份存储空间,类的方法存储于此
2.isa指针
- 每一个对象都包含一个isa指针.这个指针指向当前对象所属的类。
- [p eat];表示给p所指向的对象发送一条eat消息,调用对象的eat方法,此时对象会
顺着内部的isa指针找到存 储于类中的方法,执行。
- isa是对象中的隐藏指针,指向创建这个对象的类。
- 通过isa指针我们可以在运行的时候知道当前对象是属于那个Class(类)的
3.使用一个类创建多个对象
Car *car1 = [Car new];
Car *car2 = [Car new];
局部变量和全局变量以及成员变量对比
//成员变量以下划线开头的好处,就是可以区分局部变量和成员变量
_size = size;
}
- (int)size
{
return _size;
}
@interface Person : NSObject
{
// 写在类声明的大括号中的变量, 我们称之为 成员变量(属性, 实例变量)
// 成员变量只能通过对象来访问
// 注意: 成员变量不能离开类, 离开类之后就不是成员变量 \
成员变量不能在定义的同时进行初始化
// 存储: 堆(当前对象对应的堆的存储空间中)
// 存储在堆中的数据, 不会被自动释放, 只能程序员手动释放
int age;
}
@end
@implementation Person
@end
// 写在函数和大括号外部的变量, 我们称之为全局变量
// 作用域: 从定义的那一行开始, 一直到文件末尾
// 局部变量可以先定义在初始化, 也可以定义的同时初始化
// 存储: 静态区
// 程序一启动就会分配存储空间, 直到程序结束才会释放
int a;
int b = 10;
int main(int argc, const char * argv[]) {
// 写在函数或者代码块中的变量, 我们称之为局部变量
// 作用域: 从定义的那一行开始, 一直到遇到大括号或者return
// 局部变量可以先定义再初始化, 也可以定义的同时初始化
// 存储 : 栈
// 存储在栈中的数据有一个特点, 系统会自动给我们释放
int num = 10;
{
int value;
}
return 0;
}
函数和方法的区别
1.函数属于整个文件, 方法属于某一个类
方法如果离开类就不行
2.函数可以直接调用, 方法必须用对象或者类来调用
注意: 虽然函数属于整个文件, 但是如果把函数写在类的声明中会不识别
3.不能把函数当做方法来调用, 也不能把方法当做函数来调用
方法的注意点:
>方法可以没有声明只有实现
>方法可以只有声明没有实现, 编译不会报错, 但是运行会报错
如果方法只有声明没有实现, 那么运行时会报
reason: '+[Person demo]: unrecognized selector sent to class 0x100001140'
发送了一个不能识别的消息, 在Person类中没有+开头的demo方法
reason: '-[Person test]: unrecognized selector sent to instance 0x100400000'
类也有一个注意点:
类可以只有实现没有声明
注意: 在开发中不建议这样写
//@interface Person : NSObject
//// 对象方法声明
//- (void)test;
//// 类方法声明
//+ (void)demo;
//
//@end
@implementation Person : NSObject
// 对象方法实现
- (void)test
{
NSLog(@"test");
}
// 类方法实现
+ (void)demo
{
NSLog(@"demo");
}
@end
// 外部函数的声明
extern void sum();
// 内部函数的声明
static void minus();
// 外部函数
extern void sum()
{
printf("sum");
}
// 内部函数
static void minus()
{
printf("minus");
}
int main(int argc, const char * argv[]) {
sum();
// [Person demo];
// demo();
// [Person sum];
// [Person demo];
Person *p = [Person new];
[p test];
return 0;
}