gnustep objective-c 引用计数浅析

来源:互联网 发布:厦门软件测试工资待遇 编辑:程序博客网 时间:2024/05/16 17:02

只是浅浅的看了一下,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);}@endvoid 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平台的实现原理。


0 0
原创粉丝点击