Objective-c is a high-level language in its own right, with the bottom layer implemented by C/C++.

If you want to understand the implementation of some Objective-C apis and the real data structure of some objects, you need to convert Objective-C to C/C++.

OC language into C/C++ related commands

  • Commands to be used:
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp
Copy the code
  • Use Xcode’s own command:xcrun
  • Select the specified compilation platform (SDK) :iphoneosView all supported SDKS and execute the commandxcodebuild -sdks, the results are as follows:

  • Select the specified architecture, you can select emulator (I386), x86_64, 64bit(arm64), 32bit(armV7), because IPhone belongs to arm64 architecture **, so add parameter: -arch arm64**
  • The default isClangCompiler: neededclangRelevant command
  • If you want to support ARC, add it-fobjc-arc
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc  main.m -o main.cpp
Copy the code
  • To specify the system version of the runtime, you can add- fobjc - runtime = ios - 8.0.0
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios8.0. 0 main.m -o main.cpp
Copy the code
  • Need to specify framework:-framework, such as-framework UIKIt
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios8.0. 0 main.m -o main.cpp -framework Foundation
Copy the code

.

Knowing the above is enough to develop the xcrun command, but there are many other uses that are not covered here.

The final command used:

xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp
Copy the code

The project practice

Create an instance project and convert main.m in the project to main.cpp, as shown below:

The following screenshot shows the related files and directories:

Main.m

int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    @autoreleasepool {
        // Setup code that might create autoreleased objects goes here.
        appDelegateClassName = NSStringFromClass([AppDelegate class]);
    }
    return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}
Copy the code

Main.cpp

struct AppDelegate_IMPL {
	struct UIResponder_IMPL UIResponder_IVARS;
};
/* @end */


int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

        appDelegateClassName = NSStringFromClass(((Class (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("AppDelegate"), sel_registerName("class")));
    }
    return UIApplicationMain(argc, argv, __null, appDelegateClassName);
}
static struct IMAGE_INFO { unsigned version; unsigned flag; } _OBJC_IMAGE_INFO = { 0.2 };
Copy the code

I think when you start iOS development, there’s always a question on your mind:

So what's the underlying data structure of NSObject?Copy the code

Today, see what the NSObject class really looks like with the compile command above!

1, create a new NSObject object in main.m:

int main(int argc, char * argv[]) { NSString * appDelegateClassName; @autoreleasepool { // Setup code that might create autoreleased objects goes here. appDelegateClassName = NSStringFromClass([AppDelegate class]); // Create an NSObject object NSObject *obj = [[NSObject alloc] init]; } return UIApplicationMain(argc, argv, nil, appDelegateClassName); }Copy the code

2. Clang compiler:

struct AppDelegate_IMPL {
	struct UIResponder_IMPL UIResponder_IVARS;
};

int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

        appDelegateClassName = NSStringFromClass(((Class (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("AppDelegate"), sel_registerName("class")));

        NSObject *obj = ((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSObject"), sel_registerName("alloc")), sel_registerName("init"));

    }
    return UIApplicationMain(argc, argv, __null, appDelegateClassName);
}
Copy the code

NSObject is declared in Objective-C.

@interface NSObject <NSObject> { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-interface-ivars"  Class isa OBJC_ISA_AVAILABILITY; Pragma clang Diagnostic pop} pragma clang diagnostic pop} @interface NSObject <NSObject> {Class ISA; }Copy the code

So what is the actual data structure that it corresponds to?

In main. CPP, search for NSObject and find a structure similar to NSObject, as shown below:

struct NSObject_IMPL {
	Class isa;
};
Copy the code

IMPL is generally short for Implementation, which in turn verifies that NSObject’s underlying data structure is a structure.

That’s all for today.

Scan the following QR code, welcome to follow my personal wechat official account: Ape Perspective dynamics (ID:iOSDevSkills), you can leave a message on wechat official account, more exciting technical articles, looking forward to your participation! Discuss and grow together! Attack the lion!