Revision: 4275
          http://skim-app.svn.sourceforge.net/skim-app/?rev=4275&view=rev
Author:   hofman
Date:     2008-07-22 13:24:49 +0000 (Tue, 22 Jul 2008)

Log Message:
-----------
Rewrite method replacement code. Use class methods instead of functions.

Modified Paths:
--------------
    trunk/CIImage_BDSKExtensions.m
    trunk/NSCell_SKExtensions.m
    trunk/NSCharacterSet_SKExtensions.m
    trunk/NSScrollView_SKExtensions.m
    trunk/NSURL_SKExtensions.m
    trunk/PDFAnnotationLink_SKExtensions.m
    trunk/PDFAnnotationMarkup_SKExtensions.m
    trunk/PDFAnnotation_SKExtensions.m
    trunk/PDFDisplayView_SKExtensions.m
    trunk/PDFDocument_SKExtensions.m
    trunk/PDFPage_SKExtensions.m
    trunk/SKFindTableView.m
    trunk/SKThumbnailTableView.m
    trunk/SKTypeSelectHelper.m
    trunk/SKUtilities.h
    trunk/SKUtilities.m
    trunk/Skim.xcodeproj/project.pbxproj

Modified: trunk/CIImage_BDSKExtensions.m
===================================================================
--- trunk/CIImage_BDSKExtensions.m      2008-07-21 23:22:56 UTC (rev 4274)
+++ trunk/CIImage_BDSKExtensions.m      2008-07-22 13:24:49 UTC (rev 4275)
@@ -37,7 +37,6 @@
  */
 
 #import "CIImage_BDSKExtensions.h"
-#import "SKUtilities.h"
 
 
 @implementation CIImage (BDSKExtensions)

Modified: trunk/NSCell_SKExtensions.m
===================================================================
--- trunk/NSCell_SKExtensions.m 2008-07-21 23:22:56 UTC (rev 4274)
+++ trunk/NSCell_SKExtensions.m 2008-07-22 13:24:49 UTC (rev 4275)
@@ -54,7 +54,7 @@
 }
 
 + (void)load {
-    originalHighlightColorWithFrameInView = 
SKReplaceMethodImplementationWithSelector(self, 
@selector(highlightColorWithFrame:inView:), 
@selector(replacementHighlightColorWithFrame:inView:));
+    originalHighlightColorWithFrameInView = [self 
replaceInstanceMethodForSelector:@selector(highlightColorWithFrame:inView:) 
withInstanceMethodFromSelector:@selector(replacementHighlightColorWithFrame:inView:)];
 }
 
 @end

Modified: trunk/NSCharacterSet_SKExtensions.m
===================================================================
--- trunk/NSCharacterSet_SKExtensions.m 2008-07-21 23:22:56 UTC (rev 4274)
+++ trunk/NSCharacterSet_SKExtensions.m 2008-07-22 13:24:49 UTC (rev 4275)
@@ -70,7 +70,7 @@
 
 + (void)load {
     if ([self respondsToSelector:@selector(newlineCharacterSet)] == NO)
-        SKRegisterClassMethodImplementationWithSelector(self, 
@selector(newlineCharacterSet), @selector(replacementNewlineCharacterSet));
+        [self addMethodFromSelector:@selector(replacementNewlineCharacterSet) 
forSelector:@selector(newlineCharacterSet)];
 }
 
 @end

Modified: trunk/NSScrollView_SKExtensions.m
===================================================================
--- trunk/NSScrollView_SKExtensions.m   2008-07-21 23:22:56 UTC (rev 4274)
+++ trunk/NSScrollView_SKExtensions.m   2008-07-22 13:24:49 UTC (rev 4275)
@@ -103,10 +103,10 @@
 }
 
 + (void)load{
-    originalSetHasHorizontalScroller = 
SKReplaceMethodImplementationWithSelector(self, 
@selector(setHasHorizontalScroller:), 
@selector(replacementSetHasHorizontalScroller:));
-    originalSetAutohidesScrollers = 
SKReplaceMethodImplementationWithSelector(self, 
@selector(setAutohidesScrollers:), 
@selector(replacementSetAutohidesScrollers:));
-    originalDealloc = SKReplaceMethodImplementationWithSelector(self, 
@selector(dealloc), @selector(replacementDealloc));
-    originalTile = SKReplaceMethodImplementationWithSelector(self, 
@selector(tile), @selector(replacementTile));
+    originalSetHasHorizontalScroller = [self 
replaceInstanceMethodForSelector:@selector(setHasHorizontalScroller:) 
withInstanceMethodFromSelector:@selector(replacementSetHasHorizontalScroller:)];
+    originalSetAutohidesScrollers = [self 
replaceInstanceMethodForSelector:@selector(setAutohidesScrollers:) 
withInstanceMethodFromSelector:@selector(replacementSetAutohidesScrollers:)];
+    originalDealloc = [self 
replaceInstanceMethodForSelector:@selector(dealloc) 
withInstanceMethodFromSelector:@selector(replacementDealloc)];
+    originalTile = [self replaceInstanceMethodForSelector:@selector(tile) 
withInstanceMethodFromSelector:@selector(replacementTile)];
     
     // dictionary doesn't retain keys, so no retain cycles; pointer equality 
used to compare views
     scrollViewPlacards = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, 
NULL, &kCFTypeDictionaryValueCallBacks);

Modified: trunk/NSURL_SKExtensions.m
===================================================================
--- trunk/NSURL_SKExtensions.m  2008-07-21 23:22:56 UTC (rev 4274)
+++ trunk/NSURL_SKExtensions.m  2008-07-22 13:24:49 UTC (rev 4275)
@@ -55,8 +55,8 @@
 }
 
 + (void)load {
-    originalInitFileURLWithPath = 
SKReplaceMethodImplementationWithSelector(self, 
@selector(initFileURLWithPath:), @selector(replacementInitFileURLWithPath:));
-    originalInitWithString = SKReplaceMethodImplementationWithSelector(self, 
@selector(initWithString:), @selector(replacementInitWithString:));
+    originalInitFileURLWithPath = [self 
replaceInstanceMethodForSelector:@selector(initFileURLWithPath:) 
withInstanceMethodFromSelector:@selector(replacementInitFileURLWithPath:)];
+    originalInitWithString = [self 
replaceInstanceMethodForSelector:@selector(initWithString:) 
withInstanceMethodFromSelector:@selector(replacementInitWithString:)];
 }
 
 + (NSURL *)URLFromPasteboardAnyType:(NSPasteboard *)pasteboard {

Modified: trunk/PDFAnnotationLink_SKExtensions.m
===================================================================
--- trunk/PDFAnnotationLink_SKExtensions.m      2008-07-21 23:22:56 UTC (rev 
4274)
+++ trunk/PDFAnnotationLink_SKExtensions.m      2008-07-22 13:24:49 UTC (rev 
4275)
@@ -62,9 +62,9 @@
 
 + (void)load {
     if ([self instancesRespondToSelector:@selector(toolTip)])
-        originalToolTip = SKReplaceMethodImplementationWithSelector(self, 
@selector(toolTip), @selector(replacementToolTip));
+        originalToolTip = [self 
replaceInstanceMethodForSelector:@selector(toolTip) 
withInstanceMethodFromSelector:@selector(replacementToolTip)];
     if ([self instancesRespondToSelector:@selector(toolTipNoLabel)])
-        originalToolTipNoLabel = 
SKReplaceMethodImplementationWithSelector(self, @selector(toolTip), 
@selector(replacementToolTipNoLabel));
+        originalToolTipNoLabel = [self 
replaceInstanceMethodForSelector:@selector(toolTip) 
withInstanceMethodFromSelector:@selector(replacementToolTipNoLabel)];
 }
 
 - (BOOL)isLink { return YES; }

Modified: trunk/PDFAnnotationMarkup_SKExtensions.m
===================================================================
--- trunk/PDFAnnotationMarkup_SKExtensions.m    2008-07-21 23:22:56 UTC (rev 
4274)
+++ trunk/PDFAnnotationMarkup_SKExtensions.m    2008-07-22 13:24:49 UTC (rev 
4275)
@@ -123,9 +123,9 @@
 }
 
 + (void)load {
-    originalDealloc = SKReplaceMethodImplementationWithSelector(self, 
@selector(dealloc), @selector(replacementDealloc));
+    originalDealloc = [self 
replaceInstanceMethodForSelector:@selector(dealloc) 
withInstanceMethodFromSelector:@selector(replacementDealloc)];
     if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_4)
-        originalDrawWithBoxInContext = 
SKReplaceMethodImplementationWithSelector(self, 
@selector(drawWithBox:inContext:), 
@selector(replacementDrawWithBox:inContext:));
+        originalDrawWithBoxInContext = [self 
replaceInstanceMethodForSelector:@selector(drawWithBox:inContext:) 
withInstanceMethodFromSelector:@selector(replacementDrawWithBox:inContext:)];
     lineRectsDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, 
&kCFTypeDictionaryValueCallBacks);
 }
 

Modified: trunk/PDFAnnotation_SKExtensions.m
===================================================================
--- trunk/PDFAnnotation_SKExtensions.m  2008-07-21 23:22:56 UTC (rev 4274)
+++ trunk/PDFAnnotation_SKExtensions.m  2008-07-22 13:24:49 UTC (rev 4275)
@@ -54,7 +54,6 @@
 #import "SKPDFView.h"
 #import "NSGeometry_SKExtensions.h"
 #import "NSString_SKExtensions.h"
-#import "SKUtilities.h"
 
 
 FourCharCode SKScriptingBorderStyleFromBorderStyle(PDFBorderStyle borderStyle) 
{

Modified: trunk/PDFDisplayView_SKExtensions.m
===================================================================
--- trunk/PDFDisplayView_SKExtensions.m 2008-07-21 23:22:56 UTC (rev 4274)
+++ trunk/PDFDisplayView_SKExtensions.m 2008-07-22 13:24:49 UTC (rev 4275)
@@ -221,36 +221,35 @@
 
 #pragma mark SKSwizzlePDFDisplayViewMethods
 
-static IMP SKConditionallyReplaceMethodImplementation(Class aClass, SEL 
aSelector, IMP anImp) {
-    if ([aClass instancesRespondToSelector:aSelector])
-        return SKReplaceMethodImplementation(aClass, aSelector, anImp, YES);
-    else
-        return NULL;
-}
-
-static void SKConditionallyRegisterMethodImplementation(Class aClass, SEL 
aSelector, IMP anImp, const char *types) {
-    if ([aClass instancesRespondToSelector:aSelector] == NO)
-        SKRegisterMethodImplementation(aClass, aSelector, anImp, types, YES);
-}
-
 void SKSwizzlePDFDisplayViewMethods() {
     Class PDFDisplayViewClass = NSClassFromString(@"PDFDisplayView");
     if (PDFDisplayViewClass) {
-        originalResetCursorRects = 
SKConditionallyReplaceMethodImplementation(PDFDisplayViewClass, 
@selector(resetCursorRects), (IMP)replacementResetCursorRects);
-        originalPasswordEntered = 
SKConditionallyReplaceMethodImplementation(PDFDisplayViewClass, 
@selector(passwordEntered:), (IMP)replacementPasswordEntered);
+        if ([PDFDisplayViewClass 
instancesRespondToSelector:@selector(resetCursorRects)])
+            originalResetCursorRects = [PDFDisplayViewClass 
replaceInstanceMethodForSelector:@selector(resetCursorRects) 
withMethod:(IMP)replacementResetCursorRects];
+        if ([PDFDisplayViewClass 
instancesRespondToSelector:@selector(passwordEntered:)])
+            originalPasswordEntered = [PDFDisplayViewClass 
replaceInstanceMethodForSelector:@selector(passwordEntered:) 
withMethod:(IMP)replacementPasswordEntered];
         
         if ([[NSUserDefaults standardUserDefaults] 
boolForKey:@"SKDisableExtendedPDFViewAccessibility"]) return;
         
-        originalAccessibilityAttributeNames = 
SKConditionallyReplaceMethodImplementation(PDFDisplayViewClass, 
@selector(accessibilityAttributeNames), 
(IMP)replacementAccessibilityAttributeNames);
-        originalAccessibilityParameterizedAttributeNames = 
SKConditionallyReplaceMethodImplementation(PDFDisplayViewClass, 
@selector(accessibilityParameterizedAttributeNames), 
(IMP)replacementAccessibilityParameterizedAttributeNames);
-        originalAccessibilityAttributeValue = 
SKConditionallyReplaceMethodImplementation(PDFDisplayViewClass, 
@selector(accessibilityAttributeValue:), 
(IMP)replacementAccessibilityAttributeValue);
-        originalAccessibilityHitTest = 
SKConditionallyReplaceMethodImplementation(PDFDisplayViewClass, 
@selector(accessibilityHitTest:), (IMP)replacementAccessibilityHitTest);
-        originalAccessibilityFocusedUIElement = 
SKConditionallyReplaceMethodImplementation(PDFDisplayViewClass, 
@selector(accessibilityFocusedUIElement), 
(IMP)replacementAccessibilityFocusedUIElement);
-        
-        SKConditionallyRegisterMethodImplementation(PDFDisplayViewClass, 
@selector(accessibilityRangeForPositionAttributeForParameter:), 
(IMP)replacementAccessibilityRangeForPositionAttributeForParameter, "@@:@");
-        SKConditionallyRegisterMethodImplementation(PDFDisplayViewClass, 
@selector(accessibilityRTFForRangeAttributeForParameter:), 
(IMP)replacementAccessibilityRTFForRangeAttributeForParameter, "@@:@");
-        SKConditionallyRegisterMethodImplementation(PDFDisplayViewClass, 
@selector(accessibilityAttributedStringForRangeAttributeForParameter:), 
(IMP)replacementAccessibilityAttributedStringForRangeAttributeForParameter, 
"@@:@");
-        SKConditionallyRegisterMethodImplementation(PDFDisplayViewClass, 
@selector(accessibilityStyleRangeForIndexAttributeForParameter:), 
(IMP)replacementAccessibilityStyleRangeForIndexAttributeForParameter, "@@:@");
+        if ([PDFDisplayViewClass 
instancesRespondToSelector:@selector(accessibilityAttributeNames)])
+            originalAccessibilityAttributeNames = [PDFDisplayViewClass 
replaceInstanceMethodForSelector:@selector(accessibilityAttributeNames) 
withMethod:(IMP)replacementAccessibilityAttributeNames];
+        if ([PDFDisplayViewClass 
instancesRespondToSelector:@selector(accessibilityParameterizedAttributeNames)])
+            originalAccessibilityParameterizedAttributeNames = 
[PDFDisplayViewClass 
replaceInstanceMethodForSelector:@selector(accessibilityParameterizedAttributeNames)
 withMethod:(IMP)replacementAccessibilityParameterizedAttributeNames];
+        if ([PDFDisplayViewClass 
instancesRespondToSelector:@selector(accessibilityAttributeValue:)])
+            originalAccessibilityAttributeValue = [PDFDisplayViewClass 
replaceInstanceMethodForSelector:@selector(accessibilityAttributeValue:) 
withMethod:(IMP)replacementAccessibilityAttributeValue];
+        if ([PDFDisplayViewClass 
instancesRespondToSelector:@selector(accessibilityHitTest:)])
+            originalAccessibilityHitTest = [PDFDisplayViewClass 
replaceInstanceMethodForSelector:@selector(accessibilityHitTest:) 
withMethod:(IMP)replacementAccessibilityHitTest];
+        if ([PDFDisplayViewClass 
instancesRespondToSelector:@selector(accessibilityFocusedUIElement)])
+            originalAccessibilityFocusedUIElement = [PDFDisplayViewClass 
replaceInstanceMethodForSelector:@selector(accessibilityFocusedUIElement) 
withMethod:(IMP)replacementAccessibilityFocusedUIElement];
+            
+        if ([PDFDisplayViewClass 
instancesRespondToSelector:@selector(accessibilityRangeForPositionAttributeForParameter:)]
 == NO)
+            [PDFDisplayViewClass 
addInstanceMethod:(IMP)replacementAccessibilityRangeForPositionAttributeForParameter
 typeEncoding:"@@:@" 
forSelector:@selector(accessibilityRangeForPositionAttributeForParameter:)];
+        if ([PDFDisplayViewClass 
instancesRespondToSelector:@selector(accessibilityRTFForRangeAttributeForParameter:)]
 == NO)
+            [PDFDisplayViewClass 
addInstanceMethod:(IMP)replacementAccessibilityRTFForRangeAttributeForParameter 
typeEncoding:"@@:@" 
forSelector:@selector(accessibilityRTFForRangeAttributeForParameter:)];
+        if ([PDFDisplayViewClass 
instancesRespondToSelector:@selector(accessibilityAttributedStringForRangeAttributeForParameter:)]
 == NO)
+            [PDFDisplayViewClass 
addInstanceMethod:(IMP)replacementAccessibilityAttributedStringForRangeAttributeForParameter
 typeEncoding:"@@:@" 
forSelector:@selector(accessibilityAttributedStringForRangeAttributeForParameter:)];
+        if ([PDFDisplayViewClass 
instancesRespondToSelector:@selector(accessibilityStyleRangeForIndexAttributeForParameter:)]
 == NO)
+            [PDFDisplayViewClass 
addInstanceMethod:(IMP)replacementAccessibilityStyleRangeForIndexAttributeForParameter
 typeEncoding:"@@:@" 
forSelector:@selector(accessibilityStyleRangeForIndexAttributeForParameter:)];
     }
 }
 

Modified: trunk/PDFDocument_SKExtensions.m
===================================================================
--- trunk/PDFDocument_SKExtensions.m    2008-07-21 23:22:56 UTC (rev 4274)
+++ trunk/PDFDocument_SKExtensions.m    2008-07-22 13:24:49 UTC (rev 4275)
@@ -74,7 +74,7 @@
 + (void)load {
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
     if ([self 
instancesRespondToSelector:@selector(getPrintOperationForPrintInfo:autoRotate:)])
-        originalGetPrintOperationForPrintInfo = 
SKReplaceMethodImplementationWithSelector(self, 
@selector(getPrintOperationForPrintInfo:autoRotate:), 
@selector(replacementGetPrintOperationForPrintInfo:autoRotate:));
+        originalGetPrintOperationForPrintInfo = [self 
replaceInstanceMethodForSelector:@selector(getPrintOperationForPrintInfo:autoRotate:)
 
withInstanceMethodFromSelector:@selector(replacementGetPrintOperationForPrintInfo:autoRotate:)];
     [pool release];
 }
 

Modified: trunk/PDFPage_SKExtensions.m
===================================================================
--- trunk/PDFPage_SKExtensions.m        2008-07-21 23:22:56 UTC (rev 4274)
+++ trunk/PDFPage_SKExtensions.m        2008-07-22 13:24:49 UTC (rev 4275)
@@ -74,7 +74,7 @@
 }
 
 + (void)load {
-    originalDealloc = SKReplaceMethodImplementationWithSelector(self, 
@selector(dealloc), @selector(replacementDealloc));
+    originalDealloc = [self 
replaceInstanceMethodForSelector:@selector(dealloc) 
withInstanceMethodFromSelector:@selector(replacementDealloc)];
     bboxCache = CFDictionaryCreateMutable(NULL, 0, NULL, 
&SKNSRectDictionaryValueCallbacks);
 }
 

Modified: trunk/SKFindTableView.m
===================================================================
--- trunk/SKFindTableView.m     2008-07-21 23:22:56 UTC (rev 4274)
+++ trunk/SKFindTableView.m     2008-07-22 13:24:49 UTC (rev 4275)
@@ -172,7 +172,7 @@
 }
 
 + (void)load {
-    originalDrawWithFrameInView = 
SKReplaceMethodImplementationWithSelector(self, 
@selector(drawWithFrame:inView:), @selector(replacementDrawWithFrame:inView:));
+    originalDrawWithFrameInView = [self 
replaceInstanceMethodForSelector:@selector(drawWithFrame:inView:) 
withInstanceMethodFromSelector:@selector(replacementDrawWithFrame:inView:)];
 }
 
 @end

Modified: trunk/SKThumbnailTableView.m
===================================================================
--- trunk/SKThumbnailTableView.m        2008-07-21 23:22:56 UTC (rev 4274)
+++ trunk/SKThumbnailTableView.m        2008-07-22 13:24:49 UTC (rev 4275)
@@ -58,7 +58,7 @@
 }
 
 + (void)load {
-    originalTrackKnob = SKReplaceMethodImplementationWithSelector(self, 
@selector(trackKnob:), @selector(replacementTrackKnob:));
+    originalTrackKnob = [self 
replaceInstanceMethodForSelector:@selector(trackKnob:) 
withInstanceMethodFromSelector:@selector(replacementTrackKnob:)];
 }
 
 @end

Modified: trunk/SKTypeSelectHelper.m
===================================================================
--- trunk/SKTypeSelectHelper.m  2008-07-21 23:22:56 UTC (rev 4274)
+++ trunk/SKTypeSelectHelper.m  2008-07-22 13:24:49 UTC (rev 4275)
@@ -428,7 +428,7 @@
 }
 
 + (void)load {
-    originalMakeFirstResponder = 
(typeof(originalMakeFirstResponder))SKReplaceMethodImplementationWithSelector(self,
 @selector(makeFirstResponder:), @selector(replacementMakeFirstResponder:));
+    originalMakeFirstResponder = (typeof(originalMakeFirstResponder))[self 
replaceInstanceMethodForSelector:@selector(makeFirstResponder:) 
withInstanceMethodFromSelector:@selector(replacementMakeFirstResponder:)];
 }
 
 @end

Modified: trunk/SKUtilities.h
===================================================================
--- trunk/SKUtilities.h 2008-07-21 23:22:56 UTC (rev 4274)
+++ trunk/SKUtilities.h 2008-07-22 13:24:49 UTC (rev 4275)
@@ -3,27 +3,41 @@
 //  Skim
 //
 //  Created by Christiaan Hofman on 2/15/07.
+/*
+ This software is Copyright (c) 2008
+ Christiaan Hofman. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 
-/* Some of the following functions are inspired by OmniBase/SKUtilities.h and 
subject to the following copyright */
+#import <Cocoa/Cocoa.h>
 
-// Copyright 1997-2008 Omni Development, Inc.  All rights reserved.
-//
-// This software may only be used and reproduced according to the
-// terms in the file OmniSourceLicense.html, which should be
-// distributed with this project and can also be found at
-// <http://www.omnigroup.com/developer/sourcecode/sourcelicense/>.
-
-#import <objc/objc.h>
-#import <objc/objc-class.h>
-#import <objc/objc-runtime.h>
-
-IMP SKReplaceMethodImplementation(Class aClass, SEL aSelector, IMP anImp, BOOL 
isInstance);
-IMP SKReplaceMethodImplementationWithSelector(Class aClass, SEL aSelector, SEL 
impSelector);
-IMP SKReplaceClassMethodImplementationWithSelector(Class aClass, SEL 
aSelector, SEL impSelector);
-void SKRegisterMethodImplementation(Class aClass, SEL aSelector, IMP anImp, 
const char *types, BOOL isInstance);
-void SKRegisterMethodImplementationWithSelector(Class aClass, SEL aSelector, 
SEL impSelector);
-void SKRegisterClassMethodImplementationWithSelector(Class aClass, SEL 
aSelector, SEL impSelector);
-
 #define OBINITIALIZE \
     do { \
         static BOOL hasBeenInitialized = NO; \
@@ -32,3 +46,21 @@
             return; \
         hasBeenInitialized = YES;\
     } while (0);
+
+
[EMAIL PROTECTED] NSObject (SKExtensions)
+
++ (IMP)replaceMethodForSelector:(SEL)aSelector withMethod:(IMP)anImp;
++ (IMP)replaceInstanceMethodForSelector:(SEL)aSelector withMethod:(IMP)anImp;
++ (IMP)replaceMethodForSelector:(SEL)aSelector 
withMethodFromSelector:(SEL)impSelector;
++ (IMP)replaceInstanceMethodForSelector:(SEL)aSelector 
withInstanceMethodFromSelector:(SEL)impSelector;
+
++ (void)exchangeMethodForSelector:(SEL)aSelector 
withMethodForSelector:(SEL)otherSelector;
++ (void)exchangeInstanceMethodForSelector:(SEL)aSelector 
withInstanceMethodForSelector:(SEL)otherSelector;
+
++ (void)addMethod:(IMP)anImp typeEncoding:(const char *)types 
forSelector:(SEL)aSelector;
++ (void)addInstanceMethod:(IMP)anImp typeEncoding:(const char *)types 
forSelector:(SEL)aSelector;
++ (void)addMethodFromSelector:(SEL)impSelector forSelector:(SEL)aSelector;
++ (void)addInstanceMethodFromSelector:(SEL)impSelector 
forSelector:(SEL)aSelector;
+
[EMAIL PROTECTED]

Modified: trunk/SKUtilities.m
===================================================================
--- trunk/SKUtilities.m 2008-07-21 23:22:56 UTC (rev 4274)
+++ trunk/SKUtilities.m 2008-07-22 13:24:49 UTC (rev 4275)
@@ -15,12 +15,17 @@
 
 #import "SKUtilities.h"
 #import <Foundation/Foundation.h>
+#import <objc/objc.h>
+#import <objc/objc-class.h>
+#import <objc/objc-runtime.h>
 
 
 // wrappers around 10.5 only functions, use 10.4 API when the function is not 
defined
 
 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
 
+extern void _objc_flush_caches(Class);
+
 static Class SK_object_getClass(id object)
 {
     return object_getClass != NULL ? object_getClass(object) : object->isa;
@@ -67,6 +72,9 @@
         newMethodList->method_list[0].method_types = (char *)methodTypes;
         
         class_addMethods(aClass, newMethodList);
+        
+        // Flush the method cache
+        _objc_flush_caches(aClass);
     }
 }
 
@@ -109,14 +117,13 @@
     return isInstance ? class_getInstanceMethod(aClass, aSelector) : 
class_getClassMethod(aClass, aSelector);
 }
 
-IMP SKReplaceMethodImplementation(Class aClass, SEL aSelector, IMP anImp, BOOL 
isInstance)
+static IMP SKReplaceMethodImplementation(Class aClass, SEL aSelector, IMP 
anImp, BOOL isInstance)
 {
     Method superMethod = NULL;
     Method localMethod = SK_class_getMethod(aClass, aSelector, isInstance);
     IMP oldImp = NULL;
     Class superCls = Nil;
     Class realClass = isInstance ? aClass : SK_object_getClass(aClass);
-    extern void _objc_flush_caches(Class);
     
     if (localMethod) {
         if (superCls = SK_class_getSuperclass(aClass))
@@ -129,48 +136,69 @@
         } else {
             // Replace the method in place
             oldImp = SK_method_setImplementation(localMethod, anImp);
+            // We don't need to flush the method cach because the cache 
contains pointers to the Methods, so the cache is automatically updated
+            // See 
<http://kevin.sb.org/2006/11/16/objective-c-caching-and-method-swizzling/>
         }
-        
-        // Flush the method cache, deprecated on 10.5
-        if (_objc_flush_caches != NULL)
-            _objc_flush_caches(realClass);
     }
     
     return oldImp;
 }
 
-IMP SKReplaceMethodImplementationWithSelector(Class aClass, SEL aSelector, SEL 
impSelector)
+static void SKRegisterMethodImplementation(Class aClass, SEL aSelector, IMP 
anImp, const char *types, BOOL isInstance)
 {
-    return SKReplaceMethodImplementation(aClass, aSelector, 
SK_method_getImplementation(class_getInstanceMethod(aClass, impSelector)), YES);
+    Class realClass = isInstance ? aClass : SK_object_getClass(aClass);
+    SK_class_addMethod(realClass, aSelector, anImp, types);
 }
 
-IMP SKReplaceClassMethodImplementationWithSelector(Class aClass, SEL 
aSelector, SEL impSelector)
+static void SKRegisterMethodImplementationWithSelector(Class aClass, SEL 
aSelector, SEL impSelector, BOOL isInstance)
 {
-    return SKReplaceMethodImplementation(aClass, aSelector, 
SK_method_getImplementation(class_getClassMethod(aClass, impSelector)), NO);
+    Method method = SK_class_getMethod(aClass, impSelector, isInstance);
+    if (method)
+        SKRegisterMethodImplementation(aClass, aSelector, 
SK_method_getImplementation(method), SK_method_getTypeEncoding(method), 
isInstance);
 }
 
-void SKRegisterMethodImplementation(Class aClass, SEL aSelector, IMP anImp, 
const char *types, BOOL isInstance)
-{
-    Class realClass = isInstance ? aClass : SK_object_getClass(aClass);
-    extern void _objc_flush_caches(Class);
-    
-    SK_class_addMethod(realClass, aSelector, anImp, types);
-    
-    // Flush the method cache, deprecated on 10.5
-    if (_objc_flush_caches != NULL)
-        _objc_flush_caches(realClass);
[EMAIL PROTECTED] NSObject (SKExtensions)
+
++ (IMP)replaceMethodForSelector:(SEL)aSelector withMethod:(IMP)anImp {
+       return SKReplaceMethodImplementation(self, aSelector, anImp, NO);
 }
 
-void SKRegisterMethodImplementationWithSelector(Class aClass, SEL aSelector, 
SEL impSelector)
-{
-    Method method = class_getInstanceMethod(aClass, impSelector);
-    if (method)
-        SKRegisterMethodImplementation(aClass, aSelector, 
SK_method_getImplementation(method), SK_method_getTypeEncoding(method), YES);
++ (IMP)replaceInstanceMethodForSelector:(SEL)aSelector withMethod:(IMP)anImp {
+       return SKReplaceMethodImplementation(self, aSelector, anImp, YES);
 }
 
-void SKRegisterClassMethodImplementationWithSelector(Class aClass, SEL 
aSelector, SEL impSelector)
-{
-    Method method = class_getClassMethod(aClass, impSelector);
-    if (method)
-        SKRegisterMethodImplementation(aClass, aSelector, 
SK_method_getImplementation(method), SK_method_getTypeEncoding(method), NO);
++ (IMP)replaceMethodForSelector:(SEL)aSelector 
withMethodFromSelector:(SEL)impSelector {
+       return [self replaceMethodForSelector:aSelector withMethod:[self 
methodForSelector:impSelector]];
 }
+
++ (IMP)replaceInstanceMethodForSelector:(SEL)aSelector 
withInstanceMethodFromSelector:(SEL)impSelector {
+       return [self replaceInstanceMethodForSelector:aSelector 
withMethod:[self instanceMethodForSelector:impSelector]];
+}
+
++ (void)exchangeMethodForSelector:(SEL)aSelector 
withMethodForSelector:(SEL)otherSelector {
+       IMP imp = [self replaceMethodForSelector:aSelector 
withMethodFromSelector:otherSelector];
+       [self replaceMethodForSelector:otherSelector withMethod:imp];
+}
+
++ (void)exchangeInstanceMethodForSelector:(SEL)aSelector 
withInstanceMethodForSelector:(SEL)otherSelector {
+       IMP imp = [self replaceInstanceMethodForSelector:aSelector 
withInstanceMethodFromSelector:otherSelector];
+       [self replaceInstanceMethodForSelector:otherSelector withMethod:imp];
+}
+
++ (void)addMethod:(IMP)anImp typeEncoding:(const char *)types 
forSelector:(SEL)aSelector {
+       SKRegisterMethodImplementation(self, aSelector, anImp, types, NO);
+}
+
++ (void)addInstanceMethod:(IMP)anImp typeEncoding:(const char *)types 
forSelector:(SEL)aSelector {
+       SKRegisterMethodImplementation(self, aSelector, anImp, types, YES);
+}
+
++ (void)addMethodFromSelector:(SEL)impSelector forSelector:(SEL)aSelector {
+    SKRegisterMethodImplementationWithSelector(self, aSelector, impSelector, 
NO);
+}
+
++ (void)addInstanceMethodFromSelector:(SEL)impSelector 
forSelector:(SEL)aSelector {
+    SKRegisterMethodImplementationWithSelector(self, aSelector, impSelector, 
YES);
+}
+
[EMAIL PROTECTED]

Modified: trunk/Skim.xcodeproj/project.pbxproj
===================================================================
--- trunk/Skim.xcodeproj/project.pbxproj        2008-07-21 23:22:56 UTC (rev 
4274)
+++ trunk/Skim.xcodeproj/project.pbxproj        2008-07-22 13:24:49 UTC (rev 
4275)
@@ -1033,6 +1033,7 @@
                                45B113BF0B329A7E00DE0660 /* LICENSE */,
                                2A37F4ABFDCFA73011CA2CEA /* Classes */,
                                453DC2740B4F23E500A72509 /* Third Party Sources 
*/,
+                               CE2DE4D40B85DA1C00D0DA12 /* Miscellaneous */,
                                2A37F4AFFDCFA73011CA2CEA /* Other Sources */,
                                CE4DA8CF0B9E157E0039E89C /* Help Sources */,
                                2A37F4B8FDCFA73011CA2CEA /* Resources */,
@@ -1058,7 +1059,6 @@
                                CE070EC10B89063400733CC8 /* Foundation 
Categories */,
                                CEE1776D0DBDF54000E6C317 /* AppKit Categories 
*/,
                                CEE177700DBDF60500E6C317 /* PDFKit Categories 
*/,
-                               CE2DE4D40B85DA1C00D0DA12 /* Miscellaneous */,
                        );
                        name = Classes;
                        sourceTree = "<group>";


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 the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit

Reply via email to