示例#1
0
Method class_getInstanceMethod(Class aClass, SEL aSelector)
{
	CHECK_ARG(aClass);
	CHECK_ARG(aSelector);
	// If the class has a dtable installed, then we can use the fast path
	if (classHasInstalledDtable(aClass))
	{
		// Do a dtable lookup to find out which class the method comes from.
		struct objc_slot *slot = objc_get_slot(aClass, aSelector);
		if (NULL == slot)
		{
			slot = objc_get_slot(aClass, sel_registerName(sel_getName(aSelector)));
			if (NULL == slot)
			{
				return NULL;
			}
		}

		// Now find the typed variant of the selector, with the correct types.
		aSelector = slot->selector;

		// Then do the slow lookup to find the method.
		return class_getInstanceMethodNonrecursive(slot->owner, aSelector);
	}
	Method m = class_getInstanceMethodNonrecursive(aClass, aSelector);
	if (NULL != m)
	{
		return m;
	}
	return class_getInstanceMethod(class_getSuperclass(aClass), aSelector);
}
示例#2
0
/**
 * Checks whether the class implements memory management methods, and whether
 * they are safe to use with ARC.
 */
static void checkARCAccessors(Class cls)
{
	static SEL retain, release, autorelease, isARC;
	if (NULL == retain)
	{
		retain = sel_registerName("retain");
		release = sel_registerName("release");
		autorelease = sel_registerName("autorelease");
		isARC = sel_registerName("_ARCCompliantRetainRelease");
	}
	struct objc_slot *slot = objc_get_slot(cls, retain);
	if ((NULL != slot) && !ownsMethod(slot->owner, isARC))
	{
		objc_clear_class_flag(cls, objc_class_flag_fast_arc);
		return;
	}
	slot = objc_get_slot(cls, release);
	if ((NULL != slot) && !ownsMethod(slot->owner, isARC))
	{
		objc_clear_class_flag(cls, objc_class_flag_fast_arc);
		return;
	}
	slot = objc_get_slot(cls, autorelease);
	if ((NULL != slot) && !ownsMethod(slot->owner, isARC))
	{
		objc_clear_class_flag(cls, objc_class_flag_fast_arc);
		return;
	}
	objc_set_class_flag(cls, objc_class_flag_fast_arc);
}
示例#3
0
static inline BOOL _objc_check_class_for_custom_arr_method(Class cls, SEL sel){
	struct objc_slot *slot = objc_get_slot(cls, sel);
	if (NULL != slot && slot->owner == cls){
		cls->flags.has_custom_arr = YES;
		return YES;
	}
	return NO;
}
示例#4
0
/*
 * Returns YES if the class implements a method for the specified selector, NO
 * otherwise.
 */
static BOOL ownsMethod(Class cls, SEL sel)
{
	struct objc_slot *slot = objc_get_slot(cls, sel);
	if ((NULL != slot) && (slot->owner == cls))
	{
		return YES;
	}
	return NO;
}
示例#5
0
static void call_cxx_construct_for_class(Class cls, id obj)
{
	static SEL cxx_construct;
	if (NULL == cxx_construct)
	{
		cxx_construct = sel_registerName(".cxx_construct");
	}
	struct objc_slot *slot = objc_get_slot(cls, cxx_construct);
	if (NULL != slot)
	{
		cls = slot->owner->super_class;
		if (Nil != cls)
		{
			call_cxx_construct_for_class(cls, obj);
		}
		slot->method(obj, cxx_construct);
	}
}
示例#6
0
/**
 * Calls C++ destructors in the correct order.
 */
PRIVATE void call_cxx_destruct(id obj)
{
	static SEL cxx_destruct;
	if (NULL == cxx_destruct)
	{
		cxx_destruct = sel_registerName(".cxx_destruct");
	}
	// Don't call object_getClass(), because we want to get hidden classes too
	Class cls = classForObject(obj);

	while (cls)
	{
		struct objc_slot *slot = objc_get_slot(cls, cxx_destruct);
		cls = Nil;
		if (NULL != slot)
		{
			cls = slot->owner->super_class;
			slot->method(obj, cxx_destruct);
		}
	}
}