Hi,
I'm trying to understand how +initialize works for Swift classes. I know I can't override this in Swift, and that not all Swift classes end up being initialized in the ObjC runtime even when their swift initializer is called. I'd like to get a better understanding of what kinds of classes will be initialized with the ObjC runtime when they are first referenced. To try and figure it out, I am swizzling the +initialize method from objc code in the same app, like this:
+ (void)swizzleMethodWithClassName:(NSString *)className
methodName:(NSString *)methodName
swizzledSelector:(SEL)swizzledSelector
{
Class thisClass = [self class];
Class aClass = NSClassFromString(className);
SEL originalSelector = NSSelectorFromString(methodName);
Method originalMethod;
Method swizzledMethod;
originalMethod = class_getClassMethod(aClass, originalSelector);
swizzledMethod = class_getClassMethod(thisClass, swizzledSelector);
// Need to do this to swizzle a class method
aClass = object_getClass(aClass);
IMP originalImp = method_getImplementation(originalMethod);
IMP swizzledImp = method_getImplementation(swizzledMethod);
class_replaceMethod(aClass,
swizzledSelector,
originalImp,
method_getTypeEncoding(swizzledMethod));
class_replaceMethod(aClass,
originalSelector,
swizzledImp,
method_getTypeEncoding(swizzledMethod));
}
+(void)load {
[self swizzleMethodWithClassName:@"TestApp.TestClass" methodName:@"initialize" swizzledSelector:NSSelectorFromString(@"swizzled_initialize")];
}
+(void)swizzled_initialize {
NSLog(@"swizzled initialize");
}
Then if I define a class like this:
class TestClass { }
The first time I call TestClass()
my swizzled function is hit. Based on the stack trace, I think this is happening because the type metadata accessor includes a call to objc_opt_self
. However, I'm not sure when this happens and when this +initialize would not be called in Swift. I thought a basic Swift class like the one I had above would not need the +initialize, but it seems like the compiler still emits the objc_opt_self
call, so I'm wondering what would it take to have a Swift class that doesn't use +initialize?
Thanks!