//Create an class named "AppDelegate", and return it's name as an instance of class NSString void *createAppDelegate() { Class mySubclass = objc_allocateClassPair((Class)objc_getClass("NSObject"), "AppDelegate", 0); struct objc_selector *selName = sel_registerName("application:didFinishLaunchingWithOptions:"); class_addMethod(mySubclass, selName, (void(*))applicationdidFinishLaunching, nil); objc_registerClassPair(mySubclass); return objc_msgSend(objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), "AppDelegate"); }
int main(int argc,const char* argv[]) { //新创建一个Class对象,继承于NSObject,名字叫NSPower(用于注册一个Class,Class的名字叫NSPower) Class powerCls = objc_allocateClassPair(objc_getClass("NSObject"), "NSPower", 0); //定义一个SEL,也就是OC里面的Selector,我理解为一个方法的Key,通过这个名字可以找到一个对应的方法实现函数 SEL selFun = sel_registerName("fun"); //为这个Class添加一个方法,名字叫fun,实现为power_fun(之前声明的一个C函数) //后面这个字符串是干嘛的呢?用来说明参数的,OC语言特别为每种参数类型指定了一个编码 //比如V@:的意思是,返回值是void,第一个参数是id,第二个参数是SEL class_addMethod(powerCls, selFun, (IMP)power_fun, "V@:"); //注册这个Class,从此以后,你就可以使用NSPower这个名字来创建一个类的实例了 objc_registerClassPair(powerCls); //以下代码就是创建一个NSPower的实例,并且调用fun方法 //得到一个class的实例 Class cls = objc_getClass("NSPower"); //对这个class发送alloc消息,创建一个class对象 id obj = objc_msgSend((id)cls,sel_registerName("alloc")); //对这个对象发送一个fun消息,这样会调用到之前的power_fun方法 objc_msgSend(obj,selFun); return 0; }
void applicationdidFinishLaunching(void *receiver, struct objc_selector *selector, void *application) { Class windowClass = (Class) objc_getClass("UIWindow"); void * windowInstance = class_createInstance(windowClass, 0); objc_msgSend(windowInstance, sel_registerName("initWithFrame:"),(Rect){0,0,320,480}); //Make Key and Visiable objc_msgSend(windowInstance, sel_registerName("makeKeyAndVisible")); //Create Table View Class TableViewController = (Class) objc_getClass("UITableViewController"); void *tableViewController = class_createInstance(TableViewController, 0); objc_msgSend(tableViewController, sel_registerName("init")); void *tableView = objc_msgSend(tableViewController, sel_registerName("tableView")); objc_msgSend(tableView, sel_registerName("setDataSource:"),createDataSource()); objc_msgSend(tableView, sel_registerName("setDelegate:"),createDelegate()); Class NavController = (Class) objc_getClass("UINavigationController"); navController = class_createInstance(NavController, 0); objc_msgSend(navController, sel_registerName("initWithRootViewController:"),tableViewController); void *view = objc_msgSend(navController, sel_registerName("view")); //Add Table View To Window objc_msgSend(windowInstance, sel_registerName("addSubview:"),view); }
int main(int argc, char **argv) { id app = nullptr; id pool = reinterpret_cast<id>(objc_getClass("NSAutoreleasePool")); if (!pool) { std::cerr << "Unable to get NSAutoreleasePool!\nAborting\n"; return -1; } pool = objc_msgSend(pool, sel_registerName("alloc")); if (!pool) { std::cerr << "Unable to create NSAutoreleasePool...\nAborting...\n"; return -1; } pool = objc_msgSend(pool, sel_registerName("init")); app = objc_msgSend(reinterpret_cast<id>(objc_getClass("NSApplication")), sel_registerName("sharedApplication")); NSRunAlertPanel(CFSTR("Testing"), CFSTR("This is a simple test to display NSAlertPanel."), CFSTR("OK"), nullptr, nullptr); objc_msgSend(pool, sel_registerName("release")); }
void Init_PreGC(void) { auto_collection_control_t *control; __auto_zone = auto_zone(); if (__auto_zone == NULL) { rb_objc_no_gc_error(); } __nsobject = (void *)objc_getClass("NSObject"); control = auto_collection_parameters(__auto_zone); if (getenv("GC_DEBUG")) { control->log = AUTO_LOG_COLLECTIONS | AUTO_LOG_REGIONS | AUTO_LOG_UNUSUAL; } if (getenv("GC_DISABLE")) { gc_disabled = true; } Method m = class_getInstanceMethod((Class)objc_getClass("NSObject"), sel_registerName("finalize")); assert(m != NULL); method_setImplementation(m, (IMP)rb_obj_imp_finalize); auto_collector_disable(__auto_zone); }
void tableView_didSelectRowAtIndexPath(void *receiver, struct objc_selector *selector, void *tblview, void *indexPath) { Class ViewController = (Class) objc_getClass("UIViewController"); void * vc = class_createInstance(ViewController, 0); objc_msgSend(vc, sel_registerName("init")); char buffer[8]; int row = (int) objc_msgSend(indexPath, sel_registerName("row")); sprintf (buffer, "Item %d", row); void *label = objc_msgSend(objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"),buffer); objc_msgSend(vc, sel_registerName("setTitle:"),label); objc_msgSend(navController, sel_registerName("pushViewController:animated:"),vc,1); }
void *tableView_cellForRowAtIndexPath(void *receiver, struct objc_selector *selector, void *tblview, void *indexPath) { Class TableViewCell = (Class) objc_getClass("UITableViewCell"); void *cell = class_createInstance(TableViewCell, 0); objc_msgSend(cell, sel_registerName("init")); char buffer[7]; int row = (int) objc_msgSend(indexPath, sel_registerName("row")); sprintf (buffer, "Row %d", row); void *label = objc_msgSend(objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"),buffer); objc_msgSend(cell, sel_registerName("setText:"),label); return cell; }
int main() { Class myClass = objc_getClass("Object"); id nilClass = class_createInstance(Nil, 0); id testOne = class_createInstance (myClass, 0); /* testassert(obj->isa == [Fake class]); testassert(object_setClass(obj, [Super class]) == [Fake class]); testassert(obj->isa == [Super class]); testassert(object_setClass(nil, [Super class]) == nil); testassert(object_getClass(obj) == buf[0]); testassert(object_getClass([Super class]) == [Super class]->isa); testassert(object_getClass(nil) == Nil); testassert(0 == strcmp(object_getClassName(obj), "Super")); testassert(0 == strcmp(object_getClassName([Super class]), "Super")); testassert(0 == strcmp(object_getClassName(nil), "nil")); testassert(0 == strcmp(class_getName([Super class]), "Super")); testassert(0 == strcmp(class_getName([Super class]->isa), "Super")); testassert(0 == strcmp(class_getName(nil), "nil")); succeed(__FILE__); */ fprintf (stderr, "Done\n"); }
void * createDelegate() { Class superclass = (Class) objc_getClass("NSObject"); Class DataSource = objc_allocateClassPair(superclass, "Delegate", 0); class_addMethod(DataSource, sel_registerName("tableView:didSelectRowAtIndexPath:"), (void(*))tableView_didSelectRowAtIndexPath, nil); objc_registerClassPair(DataSource); return class_createInstance(DataSource, 0); }
Engine::Engine(): m_renderbackend(0), m_guimanager(0), m_eventmanager(0), m_soundmanager(0), m_timemanager(0), m_imagemanager(0), m_soundclipmanager(0), m_vfs(0), m_model(0), m_logmanager(0), m_cursor(0), m_settings(), m_devcaps(), m_offrenderer(0), m_changelisteners() { #ifdef USE_COCOA // The next lines ensure that Cocoa is initialzed correctly. // This is needed for SDL to function properly on MAC OS X. void* cocoa_lib; cocoa_lib = dlopen( "/System/Library/Frameworks/Cocoa.framework/Cocoa", RTLD_LAZY ); void (*nsappload)(void); nsappload = (void(*)()) dlsym( cocoa_lib, "NSApplicationLoad"); nsappload(); // Create an autorelease pool, so autoreleased SDL objects don't leak. objc_object *NSAutoreleasePool = objc_getClass("NSAutoreleasePool"); m_autoreleasePool = objc_msgSend(NSAutoreleasePool, sel_registerName("new")); #endif m_logmanager = LogManager::instance(); }
void retainNSObject(id a) { if (!impRetain) { selRetain = sel_registerName("retain:"); impRetain = class_getMethodImplementation((Class)objc_getClass("NSObject"), selRetain); } impRetain(a, selRetain); }
void releaseNSObject(id a) { if (!impRelease) { selRelease = sel_registerName("release:"); impRelease = class_getMethodImplementation((Class)objc_getClass("NSObject"), selRelease); } impRelease(a, selRelease); }
void Init_PreGC(void) { auto_collection_control_t *control; #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 __auto_zone = objc_collectableZone(); #else __auto_zone = auto_zone(); #endif if (__auto_zone == NULL) { rb_objc_no_gc_error(); } __nsobject = (void *)objc_getClass("NSObject"); control = auto_collection_parameters(__auto_zone); if (getenv("GC_DEBUG")) { control->log = AUTO_LOG_COLLECTIONS | AUTO_LOG_REGIONS | AUTO_LOG_UNUSUAL; } if (getenv("GC_DISABLE")) { gc_disabled = true; auto_collector_disable(__auto_zone); } }
PCloudApp::PCloudApp(int &argc, char **argv) : QApplication(argc, argv) { #ifdef Q_OS_MAC objc_class * cls = objc_getClass("NSApplication"); SEL sharedApplication = sel_registerName("sharedApplication"); objc_object* appInst = objc_msgSend((objc_object*) cls,sharedApplication); if(appInst != NULL) { objc_object* delegate = objc_msgSend(appInst, sel_registerName("delegate")); objc_object* delClass = objc_msgSend(delegate, sel_registerName("class")); class_addMethod((Class)delClass, sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"), (IMP)dockClickHandler,"B@:"); } #endif #ifdef Q_OS_WIN notifythread = NULL; #endif reglog=NULL; regwin=NULL; logwin=NULL; loggedmenu=NULL; settingswin=NULL; sharefolderwin=NULL; incomingshareswin=NULL; outgoingshareswin=NULL; mthread=NULL; loggedin=false; lastMessageType=-1; createMenus(); settings=new PSettings(this); tray=new QSystemTrayIcon(this); tray->setIcon(QIcon(OFFLINE_ICON)); tray->setContextMenu(notloggedmenu); tray->setToolTip("pCloud"); connect(tray, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayClicked(QSystemTrayIcon::ActivationReason))); connect(tray, SIGNAL(messageClicked()), this, SLOT(trayMsgClicked())); connect(this, SIGNAL(logInSignal(QString, QString, quint64, bool, bool, quint64, quint64, bool)), this, SLOT(logIn(QString, QString, quint64,bool, bool, quint64, quint64, bool))); connect(this, SIGNAL(showLoginSignal()), this, SLOT(showLogin())); pCloudWin = new PCloudWindow(this); pCloudWin->layout()->setSizeConstraint(QLayout::SetFixedSize); //for auto resize pCloudWin->setOnlineItems(false); tray->show(); if (settings->isSet("auth") && settings->get("auth").length() > 0){ this->authentication = settings->get("auth"); othread=new OnlineThread(this); othread->start(); } else{ othread=NULL; emit showLoginSignal(); } }
void *Routine(void *arg) { Baton *baton(reinterpret_cast<Baton *>(arg)); void *(*dlopen)(const char *, int); dlset(baton, dlopen, "dlopen"); if (baton->dlsym(RTLD_DEFAULT, "JSEvaluateScript") == NULL) dlopen(Framework(JavaScriptCore), RTLD_GLOBAL | RTLD_LAZY); void *(*objc_getClass)(const char *); dlset(baton, objc_getClass, "objc_getClass"); if (objc_getClass("WebUndefined") == NULL) dlopen(Framework(WebKit), RTLD_GLOBAL | RTLD_LAZY); void *handle(dlopen(baton->library, RTLD_LAZY | RTLD_LOCAL)); if (handle == NULL) { baton->dlerror(); return NULL; } void (*CYHandleServer)(pid_t); dlset(baton, CYHandleServer, "CYHandleServer", handle); CYHandleServer(baton->pid); return NULL; }
static BOOL init_protocols(struct objc_protocol_list *protocols) { // Protocol2 is a subclass of Protocol, so if we have loaded Protocol2 we // must have also loaded Protocol. if (nil == protocol_class2) { protocol_class = objc_getClass("Protocol"); protocol_class2 = objc_getClass("Protocol2"); } if (nil == protocol_class2 || nil == protocol_class) { return NO; } for (unsigned i=0 ; i<protocols->count ; i++) { struct objc_protocol2 *aProto = protocols->list[i]; // Don't initialise a protocol twice if (aProto->isa == protocol_class || aProto->isa == protocol_class2) { continue ;} // Protocols in the protocol list have their class pointers set to the // version of the protocol class that they expect. enum protocol_version version = (enum protocol_version)(uintptr_t)aProto->isa; switch (version) { default: fprintf(stderr, "Unknown protocol version"); abort(); case protocol_version_legacy: aProto->isa = protocol_class; break; case protocol_version_objc2: aProto->isa = protocol_class2; break; } // Initialize all of the protocols that this protocol refers to if (NULL != aProto->protocol_list) { init_protocols(aProto->protocol_list); } // Replace this protocol with a unique version of it. protocols->list[i] = unique_protocol(aProto); } return YES; }
WEAK void __halide_print(void *user_context, const char *str) { // Buy an autorelease pool because this is not perf critical and it is the // really safe thing to do. objc_id pool = objc_msgSend(objc_msgSend(objc_getClass("NSAutoreleasePool"), sel_getUid("alloc")), sel_getUid("init")); objc_id ns_str = objc_msgSend(objc_msgSend(objc_getClass("NSString"), sel_getUid("alloc")), sel_getUid("initWithUTF8String:"), str); NSLog(ns_str); objc_msgSend(ns_str, sel_getUid("release")); objc_msgSend(pool, sel_getUid("drain")); }
void *createDataSource() { Class superclass = (Class) objc_getClass("NSObject"); Class DataSource = objc_allocateClassPair(superclass, "DataSource", 0); class_addMethod(DataSource, sel_registerName("tableView:numberOfRowsInSection:"), (void(*))tableView_numberOfRowsInSection, nil); class_addMethod(DataSource, sel_registerName("tableView:cellForRowAtIndexPath:"), (void(*))tableView_cellForRowAtIndexPath, nil); objc_registerClassPair(DataSource); return class_createInstance(DataSource, 0); }
/* Default unloaded module method. */ void __objc_unloaded_module_implementation_called(id sender, SEL _cmd) { objc_msgSend(objc_getClass("__KKUnloadedModuleException"), sel_getNamed("raiseUnloadedModuleException:selector:"), sender, _cmd); }
static id incompleteProtocolClass(void) { static id IncompleteProtocolClass = 0; if (IncompleteProtocolClass == nil) { IncompleteProtocolClass = objc_getClass("__IncompleteProtocol"); } return IncompleteProtocolClass; }
PRIVATE BOOL _objc_unload_modules(struct objc_loader_module **begin, struct objc_loader_module **end, void *kernel_module) { OBJC_LOCK_RUNTIME_FOR_SCOPE(); struct objc_loader_module **module_ptr; for (module_ptr = begin; module_ptr < end; module_ptr++) { objc_debug_log("Checking module dependencies for %s\n", (*module_ptr)->name); if (!_objc_module_check_dependencies_for_unloading(*module_ptr, kernel_module)){ objc_debug_log("Failed checking module dependencies for %s\n", (*module_ptr)->name); return NO; } } objc_debug_log("No dependencies, unloading classes...\n"); /* * At this point, we can be certain that it is safe to unload all the * classes and protocols. */ _objc_unload_classes_in_kernel_module(kernel_module); objc_debug_log("Unloading protocols...\n"); for (module_ptr = begin; module_ptr < end; module_ptr++) { struct objc_loader_module *module = *module_ptr; for (int i = 0; i < module->symbol_table->protocol_count; ++i){ objc_protocol_unload(module->symbol_table->protocols[i]); } } objc_debug_log("Unloading IMPs...\n"); /* * Now for the fun part. Go through all the IMPs... */ _objc_unload_IMPs_from_kernel_module(kernel_module); objc_debug_log("All done unloading module %s.\n", module_getname(kernel_module)); objc_debug_log("SlowInit2: %p\n", objc_getClass("SlowInit2")); objc_log("Remaining classes:\n"); unsigned int count; Class *classes = objc_copyClassList(&count); for (int i = 0; i < count; ++i){ objc_log("\t [%02i] %s [%p]\n", i, class_getName(classes[i]), classes[i]); } objc_dealloc(classes, M_CLASS_TYPE); return YES; }
Class RegisterClass(old_class* cls, bool hasExt) { LOG << "Processing old ObjC class " << cls->name << std::endl; const old_class* meta = cls->isa.cls; Class conv, super; auto & g_classPointers = getClassPointers(); /* old_class* psuper = cls->super_class.cls; auto itSuper = g_classPointers.find(psuper); // TODO: may not be needed, should always be a string if (itSuper != g_classPointers.end()) super = itSuper->second; else super = reinterpret_cast<Class>(psuper); */ super = (Class) objc_getClass(cls->super_class.name); LOG << "...with superclass @" << super << std::endl; conv = objc_allocateClassPair(super, cls->name, 0); if (cls->methodList) ConvertMethodListGen(conv, cls->methodList); if (meta->methodList) ConvertMethodListGen(object_getClass(id(conv)), meta->methodList); if (cls->ivars) ConvertIvarList(conv, cls->ivars); if (cls->protocols) AddClassProtocols(conv, cls->protocols); if (hasExt && cls->ext && cls->ext->propertyLists) { LOG << "Class has EXT and a property list/lists\n"; //if (cls->info & CLS_NO_PROPERTY_ARRAY) if (true) { ConvertProperties(cls->ext->propertyList, [conv](const char* name, const objc_property_attribute_t* attr, unsigned int count) { class_addProperty(conv, name, attr, count); bug_gnustepFixPropertyCount(conv); }); } else { for (size_t i = 0; cls->ext->propertyLists[i] != nullptr; i++) { const old_property_list* l = cls->ext->propertyLists[i]; ConvertProperties(l, [conv](const char* name, const objc_property_attribute_t* attr, unsigned int count) { class_addProperty(conv, name, attr, count); bug_gnustepFixPropertyCount(conv); }); } } } objc_registerClassPair(conv); g_classPointers[cls] = conv; g_classPointers[cls->name] = conv; LOG << "ObjC class " << cls->name << " @" << conv << std::endl; return conv; }
id objc_getRequiredClass(const char *name) { CHECK_ARG(name); id cls = objc_getClass(name); if (nil == cls) { abort(); } return cls; }
std::vector<const char*> ProcessClassesOld(const struct mach_header* mh, intptr_t slide, module_info* info) { unsigned long cstrLen; void* ptr; std::vector<old_class*> vecClasses; std::set<old_class*> setClasses; std::map<const char*,old_class*> mapClassNames; std::vector<const char*> vecClassNames; // ptr = getsectdata(mh, "__TEXT", "__cstring", &cstrLen); // if (ptr) // g_cstringSection = std::pair<uintptr_t,uintptr_t>(uintptr_t(ptr), cstrLen); // else // g_cstringSection = std::pair<uintptr_t,uintptr_t>(0, 0); for (uint16_t i = 0; i < info->symtab->countClasses; i++) { old_class* cls = static_cast<old_class*>(info->symtab->classesAndCategories[i]); mapClassNames[cls->name] = cls; setClasses.insert(cls); } topology_sort(setClasses, vecClasses, [&mapClassNames](old_class* t) -> std::set<old_class*> { auto it = mapClassNames.find(t->super_class.name); return (it != mapClassNames.end()) ? std::set<old_class*>{it->second} : std::set<old_class*>(); } ); for (old_class* c : vecClasses) RegisterClass(c, info->version >= 6); // Change class names in 'super_class' from strings to pointers to Class // for (size_t i = 0; i < size / sizeof(old_class); i++) for (uint16_t i = 0; i < info->symtab->countClasses; i++) { old_class* cls = static_cast<old_class*>(info->symtab->classesAndCategories[i]); Class c = (Class) objc_getClass(cls->super_class.name); LOG << "ObjC fixup super_class @" << &cls->super_class << ": " << cls->super_class.name << " -> " << c << std::endl; cls->super_class.clsNew = c; } // Fix the same in metaclasses // for (size_t i = 0; i < size / sizeof(old_class); i++) for (uint16_t i = 0; i < info->symtab->countClasses; i++) { old_class* cls = static_cast<old_class*>(info->symtab->classesAndCategories[i])->isa.cls; Class c = (Class) objc_getMetaClass(cls->super_class.name); LOG << "ObjC fixup super_class @" << cls << ": " << cls->name << " -> " << c << std::endl; cls->super_class.clsNew = c; } //std::transform(mapClassNames.begin(), mapClassNames.end(), vecClassNames.begin(), [](const std::pair<const char*,old_class*>& p) { return p.first; }); for (auto it = mapClassNames.begin(); it != mapClassNames.end(); it++) vecClassNames.push_back(it->first); return vecClassNames; }
void Init_Set(void) { rb_cCFSet = (VALUE)objc_getClass("NSCFSet"); rb_cSet = rb_cNSSet = (VALUE)objc_getClass("NSSet"); rb_cNSMutableSet = (VALUE)objc_getClass("NSMutableSet"); rb_set_class_path(rb_cNSMutableSet, rb_cObject, "NSMutableSet"); rb_const_set(rb_cObject, rb_intern("Set"), rb_cNSMutableSet); rb_include_module(rb_cSet, rb_mEnumerable); rb_define_singleton_method(rb_cSet, "[]", rb_set_s_create, -1); rb_define_method(rb_cSet, "dup", rb_set_dup, 0); rb_define_method(rb_cSet, "clone", rb_set_clone, 0); rb_define_method(rb_cSet, "initialize", rb_set_initialize, -1); rb_define_method(rb_cSet, "to_a", rb_set_to_a, 0); rb_define_method(rb_cSet, "==", rb_set_equal, 1); rb_define_method(rb_cSet, "size", rb_set_size, 0); rb_define_method(rb_cSet, "empty?", rb_set_empty_q, 0); rb_define_alias(rb_cSet, "length", "size"); rb_define_method(rb_cSet, "&", rb_set_intersect, 1); rb_define_alias(rb_cSet, "intersect", "&"); rb_define_method(rb_cSet, "|", rb_set_union, 1); rb_define_alias(rb_cSet, "union", "|"); rb_define_alias(rb_cSet, "+", "|"); rb_define_method(rb_cSet, "merge", rb_set_merge, 1); rb_define_method(rb_cSet, "-", rb_set_subtract, 1); rb_define_method(rb_cSet, "add", rb_set_add, 1); rb_define_alias(rb_cSet, "<<", "add"); rb_define_method(rb_cSet, "add?", rb_set_add2, 1); rb_define_method(rb_cSet, "clear", rb_set_clear, 0); rb_define_method(rb_cSet, "delete", rb_set_delete, 1); rb_define_method(rb_cSet, "delete?", rb_set_delete2, 1); rb_define_method(rb_cSet, "delete_if", rb_set_delete_if, 0); rb_define_method(rb_cSet, "reject!", rb_set_reject_bang, 0); rb_define_method(rb_cSet, "each", rb_set_each, 0); rb_define_method(rb_cSet, "include?", rb_set_include, 1); rb_define_alias(rb_cSet, "member?", "include?"); rb_define_method(rb_cSet, "to_a", rb_set_to_a, 0); }
static void log_os(void) { Class NSProcessInfo = objc_getClass("NSProcessInfo"); id pi = objc_msgSend((id)NSProcessInfo, sel_registerName("processInfo")); SEL UTF8String = sel_registerName("UTF8String"); log_os_name(pi, UTF8String); log_os_version(pi, UTF8String); }
// BAF: This seems to be some garbage collection magic. Not for us mortals to look at! __private_extern__ Boolean __CFRuntimeIsFreedObject(id anObject) { if (!anObject) return false; static Class freedClass = Nil; if (!freedClass) freedClass = _objc_getFreedObjectClass(); Class cls = object_getClass(anObject); if (cls == freedClass) return true; // in 64-bit, a future class has nil isa, and calling class_getName() on // such will crash so we do this test; zombie classes are not future classes if (objc_getClass((id)cls) == nil) return false; const char *cname = class_getName(cls); if (cname && 0 == strncmp(cname, "_NSZombie_", 10)) return true; return false; }
bool OBJC_EXCHANGE_NEWCLASS_METHOD_TEMPLATE(const char* orgClassStr,const char* orgSelector, const char* newClassStr,const char* newSelector) { Class orgClass = objc_getClass(orgClassStr); Class newClass = objc_getClass(newClassStr); if(!orgClass || !newClass) { return false; } SEL orgMethod = sel_registerName(orgSelector); SEL newMethod = sel_registerName(newSelector); Method newMethodIns = class_getInstanceMethod(newClass, newMethod); /*在旧的类添加类新方法后,那么只需要交换原有的方法即可*/ Method orgMethodIns = class_getInstanceMethod(orgClass, orgMethod); /*防止方法不存在*/ if(!orgMethodIns || !newMethodIns) { return false; } IMP newMethodIMP = method_getImplementation(newMethodIns); const char *newMethodStr = method_getTypeEncoding(newMethodIns); class_addMethod(orgClass, newMethod, newMethodIMP, newMethodStr); newMethodIns = class_getInstanceMethod(orgClass, newMethod); method_exchangeImplementations(orgMethodIns, newMethodIns); return true; }
// Entry point of the application. If you don't know what this is by now, // then you probably shouldn't be reading the rest of this post. int main(int argc, char *argv[]) { // Create an @autoreleasepool, using the old-stye API. // Note that while NSAutoreleasePool IS deprecated, it still exists // in the APIs for a reason, and we leverage that here. In a perfect // world we wouldn't have to worry about this, but, remember, this is C. id autoreleasePool = objc_msgSend(objc_msgSend((id)objc_getClass("NSAutoreleasePool"), sel_registerName("alloc")), sel_registerName("init")); // Notice the use of CFSTR here. We cannot use an objective-c string // literal @"someStr", as that would be using objective-c, obviously. UIApplicationMain(argc, argv, nil, CFSTR("AppDelegate")); objc_msgSend(autoreleasePool, sel_registerName("drain")); }
static struct objc_protocol2 *unique_protocol(struct objc_protocol2 *aProto) { if (ObjC2ProtocolClass == 0) { ObjC2ProtocolClass = objc_getClass("Protocol2"); } struct objc_protocol2 *oldProtocol = protocol_for_name(aProto->name); if (NULL == oldProtocol) { // This is the first time we've seen this protocol, so add it to the // hash table and ignore it. protocol_table_insert(aProto); return aProto; } if (isEmptyProtocol(oldProtocol)) { if (isEmptyProtocol(aProto)) { return aProto; // Add protocol to a list somehow. } else { // This protocol is not empty, so we use its definitions makeProtocolEqualToProtocol(oldProtocol, aProto); return aProto; } } else { if (isEmptyProtocol(aProto)) { makeProtocolEqualToProtocol(aProto, oldProtocol); return oldProtocol; } else { return oldProtocol; //FIXME: We should really perform a check here to make sure the //protocols are actually the same. } } }