Are objective-c objects all same type of C-structure?

孤人 提交于 2019-12-23 12:28:43

问题


I want to know how the language's object-oriented features are implemented in C.

As defined in <objc/runtime.h>, id type is a pointer to a objc_object, and objc_object type is a C-structure with only one member isa storing a Class. Then where and how are the actual values of any object's instance-variables stored?

One more thing, the fact that all objective-C object-pointers can be casted to id (which is a pointer to a C-structure, where no feature such as inheritance exists), are Objective-C classes just qualifiers for the compiler, and all instances equally type of objc_object?

added:

NSObject *obj = [NSObject new];
objc_object *objStruct = (__bridge objc_object *)obj;
NSLog(@"obj: %@", NSStringFromClass(objStruct->isa));

NSString *str = [NSString new];
objc_object *strStruct = (__bridge objc_object *)str;
NSLog(@"str: %@", NSStringFromClass(strStruct->isa));

This code compiles and outputs:

obj: NSObject, str: __NSCFConstantString

Both obj and str can be casted to objc_object *, which means both variables are pointers of a same type, no?

resolved

Understood! I was misunderstanding how pointer-casting works. obj and str are pointers of different structure-types, but both commonly have Class-type member isa at the front of the memory, so can be treated as a objc_object. The code below mimics this mechanism:

typedef struct {
    int isa;
} Fake_NSObject;

typedef struct {
    int isa;
    char *string;
} Fake_NSString;

Fake_NSObject obj = {1};
Fake_NSObject *objPtr = &obj;
NSLog(@"obj: %d", objPtr->isa); // prints 1

Fake_NSString str = {2, "abc"};
Fake_NSString *strPtr = &str;
NSLog(@"str: %d", strPtr->isa); // prints 2

Fake_NSObject *objPtr2 = (Fake_NSObject *)strPtr; // this is ok.
NSLog(@"obj2: %d", objPtr2->isa); // prints 2

Fake_NSString *strPtr2 = (Fake_NSString *)objPtr; // this is invalid, but still works.
NSLog(@"str2: %d", strPtr2->isa); // prints 1

Thanks!


回答1:


Then where and how are the actual values of it's instance-variables stored?

They're stored in the same place as always -- inside the object. As you say, id represents a pointer to any kind of object. However, it doesn't define any specific type beyond that -- it doesn't say anything about the actual type of the object.

objc_object is just a base type that's equivalent to NSObject. Take a look at NSObject.h and you'll see that an instance of NSObject has a single instance variable, the isa pointer. The same is true for NSProxy, which is another root class in Objective-C. Subclasses of NSObject or NSProxy can add their own instance variables, which are appended to the parent's structure.

if all objective-C object-pointers can be casted to id, are all Objective-C classes just qualifiers for the compiler, and at runtime all those instances equally type of objc_object?

I'm not sure what you're asking here. The compiler won't stop you from sending any message to any object (although it will warn you if it thinks you're sending a message to an object that doesn't support it), so in a sense the compiler doesn't care about the various object types. On the other hand, objects of different types are different -- there's not universal type that all classes are converted to.

id is strongly analogous to void *. void * is a generic pointer, and you can cast any pointer to void *, but that doesn't mean that all pointers are equivalent. id is pretty much the same thing with the added restriction that the pointer you assign to a variable of type id has to point to an Objective-C object.



来源:https://stackoverflow.com/questions/16783557/are-objective-c-objects-all-same-type-of-c-structure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!