Revision: 3437
http://skim-app.svn.sourceforge.net/skim-app/?rev=3437&view=rev
Author: hofman
Date: 2008-02-24 05:49:16 -0800 (Sun, 24 Feb 2008)
Log Message:
-----------
Rewrite OB method swizzling functions, so they work both on Tiger and Leopard.
Use wrapper functions around new new functions on 10.5 that uses 10.4
implementation details when they're not available.
Modified Paths:
--------------
trunk/OBUtilities.m
Modified: trunk/OBUtilities.m
===================================================================
--- trunk/OBUtilities.m 2008-02-24 12:40:39 UTC (rev 3436)
+++ trunk/OBUtilities.m 2008-02-24 13:49:16 UTC (rev 3437)
@@ -16,28 +16,56 @@
#import "OBUtilities.h"
#import <Foundation/Foundation.h>
-static void _OBRegisterMethod(IMP methodImp, Class class, const char
*methodTypes, SEL selector)
+
+static IMP SK_method_getImplementation(struct objc_method *aMethod)
{
- struct objc_method_list *newMethodList;
-
- newMethodList = (struct objc_method_list *)
NSZoneMalloc(NSDefaultMallocZone(), sizeof(struct objc_method_list));
-
- newMethodList->method_count = 1;
- newMethodList->method_list[0].method_name = selector;
- newMethodList->method_list[0].method_imp = methodImp;
- newMethodList->method_list[0].method_types = (char *)methodTypes;
-
- class_addMethods(class, newMethodList);
+ return method_getImplementation != NULL ?
method_getImplementation(aMethod) : aMethod->method_imp;
+}
+
+static void SK_method_setImplementation(struct objc_method *aMethod, IMP anImp)
+{
+ if (method_setImplementation != NULL)
+ method_setImplementation(aMethod, anImp);
+ else
+ aMethod->method_imp = anImp;
+}
+
+static const char *SK_method_getTypeEncoding(struct objc_method *aMethod)
+{
+ return method_getTypeEncoding != NULL ? method_getTypeEncoding(aMethod) :
aMethod->method_types;
}
+static Class SK_class_getSuperclass(Class aClass)
+{
+ return class_getSuperclass != NULL ? class_getSuperclass(aClass) :
aClass->super_class;
+}
+
+static void SK_class_addMethod(Class aClass, SEL selector, IMP methodImp,
const char *methodTypes)
+{
+ if (class_addMethod != NULL) {
+ class_addMethod(aClass, selector, methodImp, methodTypes);
+ } else {
+ struct objc_method_list *newMethodList;
+
+ newMethodList = (struct objc_method_list *)
NSZoneMalloc(NSDefaultMallocZone(), sizeof(struct objc_method_list));
+
+ newMethodList->method_count = 1;
+ newMethodList->method_list[0].method_name = selector;
+ newMethodList->method_list[0].method_imp = methodImp;
+ newMethodList->method_list[0].method_types = (char *)methodTypes;
+
+ class_addMethods(aClass, newMethodList);
+ }
+}
+
IMP OBRegisterInstanceMethodWithSelector(Class aClass, SEL oldSelector, SEL
newSelector)
{
struct objc_method *thisMethod;
IMP oldImp = NULL;
if ((thisMethod = class_getInstanceMethod(aClass, oldSelector))) {
- oldImp = thisMethod->method_imp;
- _OBRegisterMethod(thisMethod->method_imp, aClass,
thisMethod->method_types, newSelector);
+ oldImp = SK_method_getImplementation(thisMethod);
+ SK_class_addMethod(aClass, newSelector, oldImp,
SK_method_getTypeEncoding(thisMethod));
}
return oldImp;
@@ -45,20 +73,22 @@
IMP OBReplaceMethodImplementation(Class aClass, SEL oldSelector, IMP newImp)
{
- struct objc_method *localMethod, *superMethod;
+ struct objc_method *localMethod, *superMethod = NULL;
IMP oldImp = NULL;
+ Class superCls = Nil;
extern void _objc_flush_caches(Class);
if ((localMethod = class_getInstanceMethod(aClass, oldSelector))) {
- oldImp = localMethod->method_imp;
- superMethod = aClass->super_class ?
class_getInstanceMethod(aClass->super_class, oldSelector) : NULL;
+ oldImp = SK_method_getImplementation(localMethod);
+ if (superCls = SK_class_getSuperclass(aClass))
+ superMethod = class_getInstanceMethod(superCls, oldSelector);
if (superMethod == localMethod) {
// We are inheriting this method from the superclass. We do *not*
want to clobber the superclass's Method structure as that would replace the
implementation on a greater scope than the caller wanted. In this case,
install a new method at this class and return the superclass's implementation
as the old implementation (which it is).
- _OBRegisterMethod(newImp, aClass, localMethod->method_types,
oldSelector);
+ SK_class_addMethod(aClass, oldSelector, newImp,
SK_method_getTypeEncoding(localMethod));
} else {
// Replace the method in place
- localMethod->method_imp = newImp;
+ SK_method_setImplementation(localMethod, newImp);
}
// Flush the method cache
@@ -70,9 +100,7 @@
IMP OBReplaceMethodImplementationWithSelector(Class aClass, SEL oldSelector,
SEL newSelector)
{
- struct objc_method *newMethod;
+ struct objc_method *newMethod = class_getInstanceMethod(aClass,
newSelector);
- newMethod = class_getInstanceMethod(aClass, newSelector);
-
- return OBReplaceMethodImplementation(aClass, oldSelector,
newMethod->method_imp);
+ return OBReplaceMethodImplementation(aClass, oldSelector,
SK_method_getImplementation(newMethod));
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit