iOS的结构体存储内存探究
2013-04-24 16:01
260 查看
http://iostrack.com/post/2012-07-20/40029966662
1、首先定义
typedef struct intStruct
{
int i;
}intStruct;
然后发现
intStruct ii={10};
int i = 10;
在内存的存储都是一样的:0A 00 00 00(原文写的是00 00 00 0A,此处实测结果与原文不服)
由此推断:
如果我们定义的结构体更为复杂,有多个变量,那么它们在内存中是依次排列的(不考虑大端小端的情况)。在内存中排列一致,导致intStruct和int可以相互转换。
当你在看apple开发文档时发现toll-free bridged这种字眼时(经常发生在NS***和CF***之间),表明它们是可以相互转换的,因为它们在内存中的排列是一致的。例如NSarray和CFArrayRef(NS为cocoa,CF为core foundation)
CFArrayRef arrayRef = //some value;
NSArray *array = (NSArray*)arratRef;
2、NSObject的定义
@interface NSObject<NSObject>{
Class isa;
}
在编译过程中,@interface关键字告诉编译器:请将NSObject作为objective-c的一个类名,并将它转换成一个struct:
struct NSObject{
Class isa;
};
再考虑到所有的类都是NSObject的子类,所以推测:所有的object都是c的结构体。
3、再来看下Class的定义:
typedef struct obj_class *Class;
struct obj_class{
Class isa
Class super_class
c*****t char *name
long version
long info
long instance_size
struct objc_ivar_list *ivars
struct objc_method_list **methodLists
struct objc_cache *cache
struct objc_protocol_list *protocols
}
objc_class包含了objc类所需的所有信息,例如变量列表,方法列表,满足的protocol等等。这些信息可以通过gdb将感兴趣的信息打印出来.
我们注意到,NSobject和objc_class都有一个isa变量,NSObject的isa描述它的元信息(即object的类信息),objc_class描述类的类信息(即类的元信息)。这样,同object一样,class也是一种object,它在obj_class的isa中可以记录class method(用 + 声明的方法)。
Objc中的runtime reflection就是根据这信息操作的。
4、object定义的方法的转换
@implementation MyClass
- (void)someMethod:(NSString*)param
@end
编译器会相应的转换为:
void [-someMethod:](id self, SEL _cmd, NSString *param){}
_cmd为方法的调用方(receiver), _cmd为方法签名(跟你用@selector得到的一样),后续为方法需要的参数。
当你调用方法时,objective-c会将方法调用都会转成c的方法调用。例如当你在程序里写如下语句时:
[myClass someMethod:@"bytedance"]
会相应的转换为:
objc_msgSend(myClass, @selector(someMethod:), @"bytedance")
@selector本质是一个c string,唯一与c string不同的是在整个内存空间中,同一方法签名的@selector的内存地址是相同的,这样在比较方法签名时候不需要采用同strcmp这么耗时的操作,而通过比较@selector的内存地址即可。
如果调用方没有找到相应的方法,会调用 [NSObject resolveInstanceMethod]方法给调用方一次处理的机会
1、首先定义
typedef struct intStruct
{
int i;
}intStruct;
然后发现
intStruct ii={10};
int i = 10;
在内存的存储都是一样的:0A 00 00 00(原文写的是00 00 00 0A,此处实测结果与原文不服)
由此推断:
如果我们定义的结构体更为复杂,有多个变量,那么它们在内存中是依次排列的(不考虑大端小端的情况)。在内存中排列一致,导致intStruct和int可以相互转换。
当你在看apple开发文档时发现toll-free bridged这种字眼时(经常发生在NS***和CF***之间),表明它们是可以相互转换的,因为它们在内存中的排列是一致的。例如NSarray和CFArrayRef(NS为cocoa,CF为core foundation)
CFArrayRef arrayRef = //some value;
NSArray *array = (NSArray*)arratRef;
2、NSObject的定义
@interface NSObject<NSObject>{
Class isa;
}
在编译过程中,@interface关键字告诉编译器:请将NSObject作为objective-c的一个类名,并将它转换成一个struct:
struct NSObject{
Class isa;
};
再考虑到所有的类都是NSObject的子类,所以推测:所有的object都是c的结构体。
3、再来看下Class的定义:
typedef struct obj_class *Class;
struct obj_class{
Class isa
Class super_class
c*****t char *name
long version
long info
long instance_size
struct objc_ivar_list *ivars
struct objc_method_list **methodLists
struct objc_cache *cache
struct objc_protocol_list *protocols
}
objc_class包含了objc类所需的所有信息,例如变量列表,方法列表,满足的protocol等等。这些信息可以通过gdb将感兴趣的信息打印出来.
我们注意到,NSobject和objc_class都有一个isa变量,NSObject的isa描述它的元信息(即object的类信息),objc_class描述类的类信息(即类的元信息)。这样,同object一样,class也是一种object,它在obj_class的isa中可以记录class method(用 + 声明的方法)。
Objc中的runtime reflection就是根据这信息操作的。
4、object定义的方法的转换
@implementation MyClass
- (void)someMethod:(NSString*)param
@end
编译器会相应的转换为:
void [-someMethod:](id self, SEL _cmd, NSString *param){}
_cmd为方法的调用方(receiver), _cmd为方法签名(跟你用@selector得到的一样),后续为方法需要的参数。
当你调用方法时,objective-c会将方法调用都会转成c的方法调用。例如当你在程序里写如下语句时:
[myClass someMethod:@"bytedance"]
会相应的转换为:
objc_msgSend(myClass, @selector(someMethod:), @"bytedance")
@selector本质是一个c string,唯一与c string不同的是在整个内存空间中,同一方法签名的@selector的内存地址是相同的,这样在比较方法签名时候不需要采用同strcmp这么耗时的操作,而通过比较@selector的内存地址即可。
如果调用方没有找到相应的方法,会调用 [NSObject resolveInstanceMethod]方法给调用方一次处理的机会
相关文章推荐
- 漫步IOS--指针细节3:指针定义、TypeDef别名声明、结构体内存存储
- iOS runtime探究(一): 从runtime开始理解面向对象的类到面向过程的结构体
- 第09天C语言(12):结构体-在内存中的存储细节
- ios学习之plist文件的读写以及存储位置的探究
- iOS _查询所剩内存和所剩存储空间的方法
- 《IOS_C语言》程序存储区划分、动态申请内存、内存操作函数
- C++中类和结构体在内存中的存储问题
- 结构体在内存中的存储方式
- iOS 的内存与存储区域
- C/C++中结构体与类成员变量在存储上的内存对齐问题
- C 语言编译过程 C语言中各种数据存储的不同内存区域 关于sizeof 结构体比实际的大的问题
- iOS结构体的内存分配问题
- 结构体在内存中的存储+位域分配
- sizeof:(含位域)结构体内存对齐,压缩存储
- 黑马程序员_iOS开发C语言基础之二进制内存存储解析与字符操作
- 结构体在内存中的存储方式
- 结构体的内存存储细节
- iOS开发探究--内存分配和分区
- 结构体在内存中的存储方式(转)
- IOS 区分缓存 内存 物理存储 逻辑存储