• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: objc_addMethods
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: objc_addMethods


  • Subject: Re: objc_addMethods
  • From: "b.bum" <email@hidden>
  • Date: Thu, 11 Nov 2004 15:41:54 -0800

On Nov 11, 2004, at 2:32 PM, Tim Conkling wrote:
Does anybody have any sample code showing the proper use of objc_addMethods to dynamically add methods to a class at runtime?

This is sort of me just being lazy, as I have the documentation in front of me, but I can't figure out certain things like how to correctly fill in an objc_method struct (what data goes into the method_imp field, for example?).

Are there any hazards involved in adding methods to existing classes at runtime (other than adding a method to a class that already has that method defined?)

PyObjC provides API via which you can add Python functions as methods on classes (or you can add existing Obj-C methods to other classes). Not something I would recommend for anything but debugging purposes as it introduces tremendous fragility, but quite handy in those times of need.


>>> from objc import *
>>> from Foundation import *
>>> x = NSObject.new()
>>> x.description()
u'<NSObject: 0x37f1a0>'
>>> def description(self):
...   print "Hello, World!"
...
>>> classAddMethods(NSObject, [description])
>>> x.description()
Hello, World!

Source here:

http://svn.red-bean.com/pyobjc/trunk/pyobjc/Modules/objc/module.m

Code Here:

PyDoc_STRVAR(classAddMethods_doc,
"classAddMethods(targetClass, methodsArray)\n"
"\n"
"Adds methods in methodsArray to class. The effect is similar to how \n"
"categories work. If class already implements a method as defined in \n"
"methodsArray, the original implementation will be replaced by the \n"
"implementation from methodsArray.");


static PyObject*
classAddMethods(PyObject* self __attribute__((__unused__)),
	PyObject* args, PyObject* keywds)
{
	static 	char* kwlist[] = { "targetClass", "methodsArray", NULL };
	PyObject* classObject = NULL;
	PyObject* methodsArray = NULL;
	Class targetClass;
	int methodCount;
	int methodIndex;
	struct objc_method_list *methodsToAdd;

	if (!PyArg_ParseTupleAndKeywords(args, keywds,
			"OO:classAddMethods", kwlist,
			&classObject, &methodsArray)) {
		return NULL;
	}

if (!PyObjCClass_Check(classObject)) {
PyErr_SetString(PyExc_TypeError, "base class is not an Objective-C class");
return NULL;
}


	methodsArray = PySequence_Fast(
			methodsArray, "methodsArray must be a sequence");
	if (methodsArray == NULL) return NULL;

	targetClass  = PyObjCClass_GetClass(classObject);
	methodCount  = PySequence_Fast_GET_SIZE(methodsArray);

	if (methodCount == 0) {
		Py_INCREF(Py_None);
		return Py_None;
	}

	methodsToAdd = PyObjCRT_AllocMethodList(methodCount);
	if (methodsToAdd == NULL) {
		PyErr_NoMemory();
		return NULL;
	}

	methodsToAdd->method_count = methodCount;

	for (methodIndex = 0; methodIndex < methodCount; methodIndex++) {
		PyObject* aMethod = PySequence_Fast_GET_ITEM(
				methodsArray, methodIndex);
		struct objc_method *objcMethod;

		aMethod = PyObjCSelector_FromFunction(
			NULL,
			aMethod,
			classObject,
			NULL);
		if (aMethod == NULL) {
			PyErr_SetString(PyExc_TypeError ,
			      "All objects in methodArray must be of "
			      "type <objc.selector>, <function>, "
			      " <method> or <classmethod>");
			goto cleanup_and_return_error;
		}

		/* install in methods to add */
		objcMethod = &methodsToAdd->method_list[methodIndex];
		objcMethod->method_name = PyObjCSelector_GetSelector(aMethod);
		objcMethod->method_types = strdup(
				PyObjCSelector_Signature(aMethod));
		if (objcMethod->method_types == NULL) {
			goto cleanup_and_return_error;
		}
		objcMethod->method_imp = PyObjCFFI_MakeIMPForPyObjCSelector(
			(PyObjCSelector*)aMethod);
		Py_DECREF(aMethod);
	}

	/* add the methods */
	PyObjCRT_ClassAddMethodList(targetClass, methodsToAdd);

	Py_INCREF(Py_None);
	return Py_None;

cleanup_and_return_error:
	if (methodsToAdd) free(methodsToAdd);
	return NULL;
}

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


References: 
 >objc_addMethods (From: Tim Conkling <email@hidden>)

  • Prev by Date: Re: Controller Issues with keys
  • Next by Date: Dock Quit menu item?
  • Previous by thread: objc_addMethods
  • Next by thread: How to protect Nib file from user modify?
  • Index(es):
    • Date
    • Thread