1#ifndef PyObjC_OBJC_CLASS_H 2#define PyObjC_OBJC_CLASS_H 3/*! 4 * @header objc-class.m 5 * @abstract Definition of the wrapper for Objective-C classes 6 * @discussion 7 * This module implements the wrappers for Objective-C classes, included 8 * subclasses defined in Python. 9 * 10 * The class-wrapper maintains a full __dict__ to make it easier to 11 * support introspection, and to make it easier to detect if someone 12 * does a super() call of a method. 13 * 14 * Maintaining a full dict is problematic because the Objective-C runtime 15 * is fairly dynamic and does not have hooks to detect these changes. Our 16 * only way to detect changes is to periodicly check the runtime if 17 * something has changed. See the definition for PyObjCClassObject for 18 * an explanation. 19 */ 20 21/*! 22 * @const PyObjCClass_Type 23 * @abstract The type objc.objc_class 24 */ 25extern PyTypeObject PyObjCClass_Type; 26 27/*! 28 * @function PyObjCClass_Check 29 * @abstract Check if an object is an Objective-C class 30 * @param obj An object 31 * @result Returns True if the object is an Objective-C class, false otherwise 32 */ 33#define PyObjCClass_Check(obj) PyObject_TypeCheck(obj, &PyObjCClass_Type) 34 35// The @const is not correct, but what else can we use here? 36/*! 37 * @const PyObjC_ClassExtender 38 * @discussion 39 * PyObjC_ClassExtender is either NULL or a Python function that can 40 * update a class dictionary. 41 * 42 * The interface for the extender function is: 43 * extender(super_class, class_name, class_dict) 44 * 45 * The return value of the function is ignored, it should update the 46 * class_dict (which represents the __dict__ of an Objective-C class. 47 */ 48extern PyObject* PyObjC_ClassExtender; 49 50 51/*! 52 * @struct PyObjCClassObject 53 * @abstract The type struct for Objective-C classes (Python 2.3 and later) 54 * @field base Type actual type object 55 * @field sel_to_py Mapping to speed up finding the correct Python method 56 * for a selector. 57 * @field method_magic The most recent PyObjC_methodlist_magic() for the class 58 * @field dictoffset Offset in the Objective-C instance for the instance 59 * __dict__ 60 * @field delmethod The method that implements __del__ 61 * @field hasPythonImpl True if the class is implemented in Python 62 * @field generation The value of PyObjC_MappingCount at the last time 63 * the method-list was updated. 64 * @field useKVO should the class implement automatic KVO notifications? 65 * @field protectedMethods methods whose name starts with an underscore 66 * 67 * @discussion 68 * This struct is the type-object for on Objective-C class. It stores 69 * some additional information that is used to manage the interface 70 * with the Objective-C runtime. 71 * 72 * (method_magic, generation) is used to detect if the method wrappers 73 * should be regenerated: if method_magic is no longer equal to 74 * PyObjC_methodlist_magic() the Objective-C class changed, if generation 75 * is no longer equal to PyObjC_MappingCount there are new method-mappings 76 * and we should rescan just in case one of those mappings is needed for 77 * this class. 78 * 79 * dictoffset is used by objc-object.m to find the __dict__ for instances. 80 * If the offset is 0 there is no __dict__. 81 * 82 * We store the __del__ implementation here instead of in the type itself 83 * to ensure that our teardown code is correctly called. 84 */ 85typedef struct _PyObjCClassObject { 86 PyHeapTypeObject base; 87 __strong Class class; 88 PyObject* sel_to_py; 89 int method_magic; 90 Py_ssize_t dictoffset; 91 PyObject* delmethod; 92 int hasPythonImpl; 93 int isCFWrapper; 94 int generation; 95 int useKVO; 96 PyObject* protectedMethods; 97 struct _PyObjCClassObject* meta_class; /* To be dropped */ 98} PyObjCClassObject; 99 100extern PyObject* PyObjCClass_DefaultModule; 101PyObject* PyObjCClass_New(Class objc_class); 102Class PyObjCClass_GetClass(PyObject* object); 103PyObject* PyObjCClass_FindSelector(PyObject* cls, SEL selector, BOOL class_method); 104void PyObjCClass_MaybeRescan(PyObject* class); 105int ObjC_RegisterClassProxy(Class cls, PyObject* classProxy); 106void PyObjCClass_CheckMethodList(PyObject* cls, int recursive); 107Py_ssize_t PyObjCClass_DictOffset(PyObject* cls); 108PyObject* PyObjCClass_GetDelMethod(PyObject* cls); 109void PyObjCClass_SetDelMethod(PyObject* cls, PyObject* newval); 110int PyObjCClass_HasPythonImplementation(PyObject* cls); 111PyObject* PyObjCClass_ClassForMetaClass(PyObject* meta); 112 113#endif /* PyObjC_OBJC_CLASS_H */ 114