我在玩旋转,不太清楚这一点。我的分配旋转看起来像这样:
@interface UIAlertView (Custom)
+ (id)allocCustom;
@end
@implementation UIAlertView (Custom)
+ (void)load
{
Method original;
Method mock;
original = class_getClassMethod(self, @selector(alloc));
mock = class_getClassMethod(self, @selector(allocCustom));
method_exchangeImplementations(mock, original);
}
+ (id)allocCustom
{
NSLog(@"Custom!");
return [self allocCustom];
}
@end
如果我在调用堆栈中反复调用的 NSLog 语句上暂停,我会看到:
* thread #1: tid = 0x2c388a, 0x00003a2f My App`+[UIAlertView(self=0x03825c74, _cmd=0x0327e663) allocCustom] + 31 at MYClass.m:62, queue = 'com.apple.main-thread, stop reason = breakpoint 4.1
frame #0: 0x00003a2f My App`+[UIAlertView(self=0x03825c74, _cmd=0x0327e663) allocCustom] + 31 at iBFGClientAppDelegate.m:62
frame #1: 0x036c7b42 CoreFoundation`+[NSTimeZone timeZoneWithName:] + 34
frame #2: 0x036c7a52 CoreFoundation`+[NSTimeZone systemTimeZone] + 626
frame #3: 0x036c7767 CoreFoundation`+[NSTimeZone defaultTimeZone] + 71
frame #4: 0x036e82cd CoreFoundation`CFTimeZoneCopyDefault + 45
frame #5: 0x036f8b90 CoreFoundation`CFCalendarCreateWithIdentifier + 544
frame #6: 0x03705f2c CoreFoundation`__CFLogCString + 124
frame #7: 0x03705e6e CoreFoundation`_CFLogvEx + 270
frame #8: 0x01581fbc Foundation`NSLogv + 137
frame #9: 0x01581f28 Foundation`NSLog + 27
frame #10: 0x00003a3a My App`+[UIAlertView(self=0x03825c74, _cmd=0x0327e663) allocCustom] + 42 at MYClass.m:62
frame #11: 0x036c7b42 CoreFoundation`+[NSTimeZone timeZoneWithName:] + 34
frame #12: 0x036c7a52 CoreFoundation`+[NSTimeZone systemTimeZone] + 626
frame #13: 0x036c7767 CoreFoundation`+[NSTimeZone defaultTimeZone] + 71
frame #14: 0x036e82cd CoreFoundation`CFTimeZoneCopyDefault + 45
frame #15: 0x036f8b90 CoreFoundation`CFCalendarCreateWithIdentifier + 544
frame #16: 0x03705f2c CoreFoundation`__CFLogCString + 124
frame #17: 0x03705e6e CoreFoundation`_CFLogvEx + 270
frame #18: 0x01581fbc Foundation`NSLogv + 137
frame #19: 0x01581f28 Foundation`NSLog + 27
frame #20: 0x00003a3a My App`+[UIAlertView(self=0x01800f3c, _cmd=0x0327e663) allocCustom] + 42 at MYClass.m:62
frame #21: 0x023fb8ae UIKit`UIApplicationMain + 60
frame #22: 0x0000293b My App`main(argc=1, argv=0xbfffedac) + 75 at main.m:18
似乎 timeZoneWithName: 正在回调我的自定义分配方法。显然,当 alloc 没有被旋转时,没有递归,但我对这里发生的事情感到困惑。
您的问题很可能是因为您正在使用方法allocCustom
UIAlertView
上alloc
,这是NSObject
上的方法。从我的发现来看,您可以成功切换NSObject
的 alloc 方法,但似乎您无法从子类中执行此操作。您可以通过将以下内容添加到UIAlertView
类别来查看这种情况的证据:
+ (id)alloc
{
return [super alloc];
}
通过这样做,它现在可以正常工作。但是由于alloc
是一个NSObject
的方法,并且显然不会被UIAlertView
覆盖,因此您可以删除方法重排,并将代码添加到被覆盖的alloc
方法中:
+ (id)alloc
{
NSLog(@"Custom!");
return [super alloc];
}
现在,如果Apple将来更改了其实现并出于某种原因在UIAlertView
中覆盖了alloc
,这可能有点危险。在这种情况下,我认为您的实现将覆盖他们的实现,尽管我认为确切的行为在技术上尚未定义。
我不是方法旋转方面的专家,但我猜因为你的allocCustom
是一个类方法,self
实际上指的是类本身。你真正想要的是这样的东西
+(id) allocCustom {
id obj = calloc(class_getInstanceSize(self), 1);
obj->isa = self;
obj->retainCount = 1;
return obj;
}
此链接可能对您有用: https://www.mikeash.com/pyblog/friday-qa-2013-01-25-lets-build-nsobject.html