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

I want to know how the object-oriented functions of the language are implemented in C.

As defined in <objc/runtime.h> , the id type is a pointer to objc_object , and the type objc_object is a C structure with one isa member that stores Class . Then, where and how are the actual values โ€‹โ€‹of any object instances stored?

One more thing: the fact that all pointers to objective-C objects can be added to id (which is a pointer to a C structure where there is no function like inheritance) are objective-C classes, qualifiers for the compiler, and all instances same type objc_object ?

added by:

 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 translated into objc_object * , which means that both variables are pointers of the same type, no?

allowed

Got it! I did not understand how pointer casting works. obj and str are pointers to different types of structure, but both usually have an element of type isa in front of the memory, so it can be thought of as objc_object . The code below imitates 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!

+4
source share
1 answer

Then, where and what are the actual values โ€‹โ€‹of the instance variables stored by him?

They are stored in the same place as always, inside the object. As you say, id is a pointer to any object. However, it does not define any particular type, except for this - it does not say anything about the actual type of the object.

objc_object is just the base type equivalent to NSObject . Take a look at NSObject.h and you will see that the NSObject instance has one 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 added to the parent structure.

if all objective-C object pointers can be dropped into id, are all objective-C classes that are just qualifiers for the compiler, and at runtime are all these instances equal to the type of objc_object?

I'm not sure what you are asking here. The compiler will not stop you from sending any messages to any object (although it will warn you if it thinks you are sending a message to an object that does not support it), therefore, in a sense, the compiler does not care about different types of objects. On the other hand, objects of different types are different - there is no universal type into which all classes are transformed.

id very similar to void * . void * is a generic pointer, and you can use any pointer to void * , but that does not mean that all pointers are equivalent. id is pretty much the same with the added constraint that the pointer that you assign to a variable of type id should point to an objective-C object.

+5
source

Source: https://habr.com/ru/post/1483071/


All Articles