Cocoa中有幾個單例類,如UIApplication,NSNotificationCenter。現在,我想找到所有單身人士的課程,我有什麼建議可以快速找到他們?找到所有單身的可可類?
我正在處理一個巨大的代碼庫,我需要將系統單例對象從定製的單例中分離出來。
Cocoa中有幾個單例類,如UIApplication,NSNotificationCenter。現在,我想找到所有單身人士的課程,我有什麼建議可以快速找到他們?找到所有單身的可可類?
我正在處理一個巨大的代碼庫,我需要將系統單例對象從定製的單例中分離出來。
Objective-C運行時hackery!有趣!
現在,在我繼續之前,我會提出免責聲明,我絕不會推薦在實際運輸代碼中放置任何類似的東西,如果這樣做,這完全不是我的錯。不過,這對於教育目的可能很有趣。
這不會是一門精確的科學,因爲語言本身沒有任何「單身人士」的實際概念。基本上,我們只是尋找具有特定贈品前綴的類方法的Objective-C類。如果我們找到其中之一,那麼我們很有可能擁有一個單身人士。
考慮到這一點:
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
static BOOL ClassIsSingleton(Class class) {
unsigned int methodCount = 0;
Method *methods = class_copyMethodList(object_getClass(class), &methodCount);
@try {
for (unsigned int i = 0; i < methodCount; i++) {
Method eachMethod = methods[i];
// only consider class methods with no arguments
if (method_getNumberOfArguments(eachMethod) != 2) {
continue;
}
char *returnType = method_copyReturnType(eachMethod);
@try {
// only consider class methods that return objects
if (strcmp(returnType, @encode(id)) != 0) {
continue;
}
}
@finally {
free(returnType);
}
NSString *name = NSStringFromSelector(method_getName(methods[i]));
// look for class methods with telltale prefixes
if ([name hasPrefix:@"shared"]) {
return YES;
} else if ([name hasPrefix:@"standard"]) {
return YES;
} else if ([name hasPrefix:@"default"]) {
return YES;
} else if ([name hasPrefix:@"main"]) {
return YES;
} // feel free to add any additional prefixes here that I may have neglected
}
}
@finally {
free(methods);
}
return NO;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSMutableArray *singletons = [NSMutableArray new];
int classCount = objc_getClassList(NULL, 0);
Class *classes = (Class *)malloc(classCount * sizeof(Class));
@try {
classCount = objc_getClassList(classes, classCount);
for (int i = 0; i < classCount; i++) {
Class eachClass = classes[i];
if (ClassIsSingleton(eachClass)) {
[singletons addObject:NSStringFromClass(eachClass)];
}
}
}
@finally {
free(classes);
}
NSLog(@"Singletons: %@", singletons);
}
return 0;
}
非常聰明!怎麼樣,對於每個返回對象的類方法,調用它,檢查該對象是否是該類的一個實例。如果是,則再次調用該方法並比較兩個對象的強相等性。如果他們是一樣的,那就更好的證明你找到了一個單身人士。 – danh
這似乎是一個好主意,直到有人引入瞭如下方法: +(NSError *)eraseTheHardDrive; :-P –
您應該限制自己調用以init開頭的方法。 實際上,您可能會通過調用alloc方法兩次並比較這些方法以獲得確切的相等性,從而獲得良好的刺戳效果。不要讓對象改變以正式初始化自己。當然,有些單例不使用這種模式,但這是一個開放式問題 –
在Xcode中,您可以按Command-Shift-O組合(字母「哦」,而不是數字零),然後搜索「共享」,你會看到一個相當有前途的開局您也可以搜索「default」和「main」,以查找其他類似單身的對象。但也許你可以詳細說明你的意思是「我需要將系統單例對象從定製的單例中分離出來」。什麼是「系統單身人士」,這是什麼「定製單身人士」?請只編輯/澄清你的問題,而不是在下面發表評論。我試圖理解你想解決什麼問題... – Rob
你也可以通過按命令2來使用「符號導航器」,然後再次搜索「默認」。您需要取消選中搜索框旁邊的「僅顯示項目定義的符號」選項。然後,您可以快速瀏覽,關注那些'class'屬性。 – Rob