小编Lui*_*BOL的帖子

实例变量和方法如何存储在Objective-C 2.0对象中?

在Objective-C的遗留版本中,objc_class结构实现如下:

struct objc_class {
    Class isa;
    Class super_class;
    const 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;
};
Run Code Online (Sandbox Code Playgroud)

因此,表示对象的结构存储指向对象类的指针,指向对象超类的指针,对象的类名,对象的版本,信息和实例大小,对象的实例变量列表,对象的方法列表,对象的缓存和对象的协议列表.在表示对象的结构中存在这些字段是非常容易理解的,因为它们中的每一个都存储有关该对象的信息.

但是,相同的struct objc_class的Objective-C 2.0实现是这样的:

struct objc_class {
    Class isa;
};
Run Code Online (Sandbox Code Playgroud)

因此,在这个版本的objc_class中,struct中只有一个字段:指向对象类结构的指针.

那么,我的问题是,对象的其他信息是如何存储在Objective-C 2.0中的,因为结构中只有一个表示对象的字段?

objective-c objective-c-runtime

5
推荐指数
1
解决办法
347
查看次数

为什么这个Block没有在其描述符中复制和处理指针?

根据该Block_private.h文件,只要在Objective-c文件中声明块,就会在目标文件中创建以下结构来表示它:

struct Block_descriptor {
    unsigned long int reserved;
    unsigned long int size;
    void (*copy)(void *dst, void *src);
    void (*dispose)(void *);
};

struct Block_layout {
    void *isa;
    int flags;
    int reserved; 
    void (*invoke)(void *, ...);
    struct Block_descriptor *descriptor;
    /* Imported variables. */
};
Run Code Online (Sandbox Code Playgroud)

但是,当我生成一个程序集文件时,with clang -S ...,from

int(^squared)(int) = ^(int i) {
    return i*i;
};
Run Code Online (Sandbox Code Playgroud)

我得到代表块的以下代码段:

    .type   .L.str210,@object       # @.str210
.L.str210:
    .asciz   "i12@?0i8"
    .size   .L.str210, 9

    .type   __block_descriptor_tmp,@object # @__block_descriptor_tmp
    .section    .rodata,"a",@progbits
    .align  16
__block_descriptor_tmp:
    .quad   0                       # …
Run Code Online (Sandbox Code Playgroud)

compilation objective-c objective-c-blocks

5
推荐指数
1
解决办法
257
查看次数

如何在NSObject中实现保留计数?

我的问题是当前版本的Foundation(或Objective-C运行时库,因为它似乎在那里)如何实现NSObject派生对象的保留计数?正如我在NSObject.mm上看到的那样,retain countNSObject界面体中没有调用ivar .相反,似乎有一种表或映射包含每个对象的引用计数器.但是,如果保留计数真的与地图做,是不是retainrelease行动与这种实现(因为太贵了,在这种情况下,有必要锁定和解锁互斥,查找地图,找到合适的对象,除了事实那么,在多线程环境中,一次只能保留/释放一个对象)?

我没有找到相关的新对象的分配时,保留计数器设置为1东西,无论是在_objc_rootAllocWithZoneNSObject.mm(这似乎是被调用的函数[NSObject alloc])也不_class_createInstanceFromZoneobjc-runtime-new.mm(即后来被称为_objc_rootAllocWithZone.

cocoa objective-c objective-c-runtime nsobject retaincount

5
推荐指数
1
解决办法
867
查看次数

forwardInvocation如何调用?

仅查看Objective-C运行时库,当消息发送到不响应它的对象时,运行时系统为接收者提供了另一个处理消息的机会.因此,接收者的forward::方法(如果实现的话)被调用.但是,看看NSObject.mm,NSObject似乎没有实现forward::.

那么,如何NSObjectforwardInvocation:方法被调用,因为需要转发时运行系统调用的唯一的事情是forward::?Foundation是否使用objc_setForwardHandler(runtime.h)设置一个新的处理程序,forwardInvocation:只要发送到NSObject对象的消息需要转发,它就会调用?

forwarding objective-c objective-c-runtime nsobject nsinvocation

5
推荐指数
1
解决办法
3638
查看次数

GCC/Clang的-framework选项是否适用于Linux?

在OSX的开发环境中,存在框架的概念.框架是一种包含头,共享库和其他有用东西的包.可以将框架传递给编译器,以便编译器在搜索路径中包含其标头,并使用其共享库将程序与它们链接.

因此,例如,如果-framework FrameworkName在OSX上传递给gcc或clang,编译器会查找/System/Library/Frameworks目录以查找FrameworkName.framework目录.如果找到,编译器将包含其标头并将程序与其共享库链接.

那么,这个超级有用的功能是否适用于Linux?gcc或clang是否认可-frameworkLinux上的选项?当我在Linux上键入此选项时,编译器似乎无法识别它,但这可能是因为我需要在它之前设置框架目录路径.是否有任何特殊技巧可以使它在Linux上运行?或者这在这个平台上绝对不可能?

gcc frameworks clang compiler-options

5
推荐指数
1
解决办法
2487
查看次数

NSObject类现在是Objective-C运行时库的一部分(而不是Foundation组件)吗?

看一下Mac OS X 10.8版本的Objective-C运行时库源代码,我注意到它有一个NSObject.mm文件.顾名思义,它有NSObject类实现,以及内置自动释放池和保留计数实现.

但是,Mountain Lion之前的ObjC运行时库的版本没有实现NSObject该类(它们没有NSObject.mm文件,正如您可以在Mac OS X 10.7的Objective-C运行时库源代码中看到的那样,例如).

那么这是否真的意味着NSObject该类现在是Objective-C运行时库的一部分而不是作为Foundation库组件?如果是,为什么?是否要-framework Foundation在子类化时避免与整个Foundation库(with )链接NSObject

cocoa objective-c objective-c-runtime foundation nsobject

5
推荐指数
1
解决办法
703
查看次数

如何在Linux上使用clone()创建真正的线程?

我正在尝试使用clone()创建一个新线程.使用以下代码(...):

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define _SCHED_H 1
#define __USE_GNU 1
#include <bits/sched.h>

#define STACK_SIZE 4096

int func(void *arg) {
    printf("Inside func.\n");
    sleep(1);
    printf("Terminating func...\n");

    return 0;
}

int main() {
    printf("This process pid: %u\n", getpid());
    char status_file[] = "/proc/self/status";
    void *child_stack = malloc(STACK_SIZE);
    int thread_pid;

    printf("Creating new thread...\n");
    thread_pid = clone(&func, child_stack+STACK_SIZE, CLONE_SIGHAND|CLONE_FS|CLONE_VM|CLONE_FILES, NULL);
    printf("Done! Thread pid: %d\n", thread_pid);

    FILE *fp = fopen(status_file, "rb");

    printf("Looking into %s...\n", status_file);

    while(1) {
        char ch = fgetc(fp);
        if(feof(fp)) …
Run Code Online (Sandbox Code Playgroud)

linux multithreading process

5
推荐指数
1
解决办法
7001
查看次数

CFMutableArray超出其容量

考虑到我有一个CFMutableArray使用以下函数调用创建的对象:

CFMutableArrayRef marray = CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks);
Run Code Online (Sandbox Code Playgroud)

根据CFMutableArray文档,的第二个参数CFArrayCreateMutable,这被称为capacity是"可以由新的数组被包含的值的最大数量.该阵列开始空并能长到这个数值(它可以具有更小) .传递0指定最大容量不受限制.该值不得为负数."

但是,如果我向我的新数组附加多个值,它会不断增长.我的意思是,如果新数组已经有一个值并且我附加了一个新CFArrayAppendValue(marray, newValue)值,则存储该值并且数组计数变为2,超过其容量.

那么,为什么会这样呢?我误解了文档吗?

cocoa core-foundation nsarray ios

5
推荐指数
1
解决办法
792
查看次数

为什么根类的元类的超类不是NULL指针?

在objective-c运行时,类由以下结构表示:

typedef struct class_t {
    struct class_t *isa;    // Points to the class' meta class
    struct class_t *super;  // Points to the class' super class
    Cache cache;
    IMP *vtable;
    union {
        class_ro_t *rodata;
        class_rw_t *rwdata;
    };
} class_t;
Run Code Online (Sandbox Code Playgroud)

当一个MyClass类是一个根类而不是一个元类时,它的超级成员是一个NULL指针(这是可以理解的,因为它是一个根类,因此它没有超类).但是,如果我们得到同MyClass一根类的isa成员(指向MyClass'meta class),并且我们得到该isa成员的超级成员,它不是NULL指针,而是指向MyClass(不是元类)的指针.非元根类的元类的超类不应该是NULL指针(作为非元根类的超类)吗?既然不是,那它应该是什么?

我问这个是因为,事实上的方式,如果methodXMyClass根类的实例方法(不是类方法),语句[MyClass methodX] 会调用methodX(它实际上是),不应该发生什么(再次,因为methodX是实例方法,而不是类方法,所以它不应该响应[MyClass methodX]语句).

class objective-c objective-c-runtime

4
推荐指数
1
解决办法
294
查看次数

如何从`callq func @ PLT`获取`func`的实际地址

在我的Linux程序中,我需要一个接收地址的函数,addr并检查callq放置的指令是否addr正在调用func从共享库加载的特定函数.我的意思是,我需要检查自己是否有这样的事情callq func@PLTaddr.

那么,在Linux上,如何funccallq func@PLT指令中获取函数的真实地址?

linux assembly function shared-libraries

4
推荐指数
1
解决办法
1332
查看次数