Esempio n. 1
0
File: class.c Progetto: MSch/MacRuby
void
rb_define_object_special_methods(VALUE klass)
{
    RCLASS_SET_VERSION(*(VALUE *)klass,
	    (RCLASS_VERSION(*(VALUE *)klass) | RCLASS_HAS_ROBJECT_ALLOC));

    rb_objc_define_method(*(VALUE *)klass, "new",
	    rb_class_new_instance_imp, -1);
    rb_objc_define_method(klass, "dup", rb_obj_dup, 0);
    rb_objc_define_private_method(klass, "initialize", rb_objc_init, -1);
    rb_objc_define_private_method(klass, "initialize_copy",
	    rb_obj_init_copy, 1);
    rb_objc_define_method(klass, "hash", rb_obj_id, 0);

    // To make sure singleton classes will be filtered.
    rb_objc_define_method(*(VALUE *)klass, "superclass", rb_obj_superclass, 0);
    rb_objc_define_method(klass, "class", rb_obj_class, 0);

    rb_objc_install_method(*(Class *)klass, selAllocWithZone,
	    (IMP)rb_obj_imp_allocWithZone);
    rb_objc_install_method((Class)klass, selIsEqual,
	    (IMP)rb_obj_imp_isEqual);
    rb_objc_install_method((Class)klass, selInit, (IMP)rb_obj_imp_init);
    rb_objc_install_method((Class)klass, selDescription,
	    (IMP)rb_obj_imp_description);

    // Create -copyWithZone:, since the method doesn't exist yet we need to
    // find the type encoding somewhere, here we check Symbol since it's
    // created very early. 
    Method m = class_getInstanceMethod((Class)rb_cSymbol, selCopyWithZone);
    assert(m != NULL);
    class_replaceMethod((Class)klass, selCopyWithZone, 
	    (IMP)rb_obj_imp_copyWithZone, method_getTypeEncoding(m));
}
Esempio n. 2
0
void SwizzInstanceMethod(Class origClass, Class replaceClass, SEL origSel, SEL replaceSel)
{
    Method origMethod = class_getInstanceMethod(origClass, origSel);
    Method newMethod = class_getInstanceMethod(replaceClass, replaceSel);
    if(class_addMethod(origClass, origSel, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
        class_replaceMethod(origClass, replaceSel, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
    else
        method_exchangeImplementations(origMethod, newMethod);
}
Esempio n. 3
0
static bool
reinstall_method_maybe(Class klass, SEL sel, const char *types)
{
    Method m = class_getInstanceMethod(klass, sel);
    if (m == NULL) {
	return false;
    }

    rb_vm_method_node_t *node = GET_CORE()->method_node_get(m);
    if (node == NULL) {
	// We only do that for pure Ruby methods.
	return false;
    }

    GET_CORE()->retype_method(klass, node, method_getTypeEncoding(m), types);
    return true;
}
Esempio n. 4
0
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;
}