只是浅浅的看了一下,gnustep是有源代码的,可以到官网下载看看。
是学习了ios与os x多线程和内存管理一书的实验代码。
#import <Foundation/Foundation.h>
@interface ClassA: NSObject
{
int k;
}
-(void) print;
@end
@implementation ClassA
-(id) initWithK: (NSNumber *) number
{
if (self = [super init])
{
k = [number intValue];
}
return self;
}
-(void) print
{
NSLog(@"k=0x%08x", k);
}
@end
void print_buf(char *buf, int length, int mode)
{
int i;
printf("buf addr=%p length=%d\n", buf, length);
for (i = 0; i < length; ++i)
{
if (mode == 0)
{
printf("%02x", (unsigned char)buf[i]);
}
else
{
printf("%02c", (unsigned char)buf[i]);
}
if ((i + 1) % 8 == 0)
{
printf(" ");
}
}
printf("\n");
}
int main(const int arg, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
char *b;
ClassA *ca = [[ClassA alloc]initWithK: [NSNumber numberWithInt: 0xDEADBEEF]];
b = (char *)ca;
NSLog(@"ca addr=%p", ca);
[ca print];
NSLog(@"retainCount=%i", [ca retainCount]);
print_buf(b - 8, 16, 0);
[ca retain];
print_buf(b - 8, 16, 0);
[ca retain];
print_buf(b - 8, 16, 0);
NSLog(@"retainCount=%i", [ca retainCount]);
[ca release];
print_buf(b - 8, 16, 0);
[ca release];
print_buf(b - 8, 16, 0);
NSLog(@"retainCount=%i", [ca retainCount]);
printf("1 value=0x%08x\n", b, *(int *)b);
printf("2 value=0x%08x\n", *((int *)*(int *)b));
printf("3 value=0x%08x\n", *((int *)*((int *)*(int *)b)));
print_buf((char *)(*((int *)*(int *)b)), 8, 1);
[ca release];
[pool drain];
return 0;
}
在windows下的输出
2015-02-10 09:22:05.626 cpro[992] ca addr=0x29b1078
2015-02-10 09:22:05.629 cpro[992] k=0xdeadbeef
2015-02-10 09:22:05.633 cpro[992] retainCount=1 这里输出retainCount是1
buf addr=029B1070 length=16
0000000000000000 c0304000efbeadde 注意索引位置4-7的地方是0 k值在对象开始地址偏移4个字节的位置
那么对象开始地址的4个字节的意义是什么,估计应该和oop有关的,虚表继承之类的
buf addr=029B1070 length=16
0000000001000000 c0304000efbeadde
buf addr=029B1070 length=16
0000000002000000 c0304000efbeadde 注意索引位置4-7的地方是2
2015-02-10 09:22:05.637 cpro[992] retainCount=3 这里输出retainCount是3
buf addr=029B1070 length=16
0000000001000000 c0304000efbeadde 注意索引位置4-7的地方是1
buf addr=029B1070 length=16
0000000000000000 c0304000efbeadde
2015-02-10 09:22:05.641 cpro[992] retainCount=1 这里输出retainCount是3
1 value=0x029b1078
2 value=0x00403040
3 value=0x670170c0
4 value=0x670170c0
buf addr=00403040 length=8
0?p00g0?p00g
基本上就是retainCount=索引位置4-7的地方的值+1,在分配对象前面加4个字节的头部用来存储索引计数。对于实例变量k值(这里是0xdeadbeef)前面的四个字节的意义,可以用静态反汇编工具或windows下的debug工具看一下,可能还不如看源码来的快。注意:这里没有深究的原因是,gnustep和apple的实现是完全不同的,gnustep在windows下的框架只是模仿cocoa的,内部可能完全不同。所以,对于理解apple平台只是有点帮助,并不是apple平台的实现原理。