if (!zone && fast) { // isa 与 对象绑定 (关联前obj为id类型,关联后obj变为实际的类型) obj->initInstanceIsa(cls, hasCxxDtor); } else { // Use raw pointer isa on the assumption that they might be // doing something weird with the zone or RR. obj->initIsa(cls); }
/// Does this runtime provide entrypoints that are likely to be faster /// than an ordinary message send of the "alloc" selector? /// /// The "alloc" entrypoint is guaranteed to be equivalent to just sending the /// corresponding message. If the entrypoint is implemented naively as just a /// message send, using it is a trade-off: it sacrifices a few cycles of /// overhead to save a small amount of code. However, it's possible for /// runtimes to detect and special-case classes that use "standard" /// alloc behavior; if that's dynamically a large proportion of all /// objects, using the entrypoint will also be faster than using a message /// send. /// /// When this method returns true, Clang will turn non-super message sends of /// certain selectors into calls to the corresponding entrypoint: /// alloc => objc_alloc /// allocWithZone:nil => objc_allocWithZone
boolshouldUseRuntimeFunctionsForAlloc()const{ switch (getKind()) { case FragileMacOSX: returnfalse; case MacOSX: returngetVersion() >= VersionTuple(10, 10); case iOS: returngetVersion() >= VersionTuple(8); case WatchOS: returntrue;
case GCC: returnfalse; case GNUstep: returnfalse; case ObjFW: returnfalse; } llvm_unreachable("bad kind"); }