IOS高级开发~Runtime(三)

11、系统类的方法实现部分替换

  • (void) methodExchange {

Method m1 = class_getInstanceMethod([NSStringclass],@selector(lowercaseString));

Method m2 = class_getInstanceMethod([NSStringclass],@selector(uppercaseString));

method_exchangeImplementations(m1, m2);

NSLog(@”%@”, [@”sssAAAAss”lowercaseString]);

NSLog(@”%@”, [@”sssAAAAss”uppercaseString]);

}

打印结果:(仔细看log)

2013-07-26 16:33:22.776 HighOC[7104:c07] SSSAAAASS

2013-07-26 16:33:22.778 HighOC[7104:c07] sssaaaass

12、自定义类的方法实现部分替换

  • (void) justLog1 {

NSLog(@”justLog1”);

}

  • (void) justLog2 {

NSLog(@”justLog2”);

}

  • (void) methodSetImplementation {

Method method = class_getInstanceMethod([ClassMethodViewCtrclass],@selector(justLog1));

<span class="s1">IMP</span> originalImp = <span class="s3">method_getImplementation</span>(method);

Method m1 = class_getInstanceMethod([ClassMethodViewCtrclass],@selector(justLog2));

method_setImplementation(m1, originalImp);

}

//[self methodSetImplementation];

//[self justLog2];

 

13、覆盖系统方法

IMP cFuncPointer;

IMP cFuncPointer1;

IMP cFuncPointer2;

NSString* CustomUppercaseString(idself,SEL_cmd){

printf(真正起作用的是本函数CustomUppercaseString\r\n”);

<span class="s2">NSString</span> *string = <span class="s5">cFuncPointer</span>(<span class="s1">self</span>,<span class="s1">_cmd</span>);

<span class="s1">return</span> string;

}

NSArray* CustomComponentsSeparatedByString(idself,SEL_cmd,NSString *str){

printf(真正起作用的是本函数CustomIsEqualToString\r\n”);

<span class="s1">return</span> <span class="s5">cFuncPointer1</span>(<span class="s1">self</span>,<span class="s1">_cmd</span>, str);

}

//不起作用,求解释

bool CustomIsEqualToString(idself,SEL_cmd,NSString *str) {

printf(真正起作用的是本函数CustomIsEqualToString\r\n”);

<span class="s1">return</span> <span class="s5">cFuncPointer2</span>(<span class="s1">self</span>,<span class="s1">_cmd</span>, str);

}

  • (void) replaceMethod{

cFuncPointer = [NSStringinstanceMethodForSelector:@selector(uppercaseString)];

<span class="s2">class_replaceMethod</span>([<span class="s2">NSString</span><span class="s2">class</span>],<span class="s1">@selector</span>(uppercaseString), (<span class="s1">IMP</span>)<span class="s5">CustomUppercaseString</span>,<span class="s7">"@@:"</span>);

<span class="s5">cFuncPointer1</span> = [<span class="s2">NSString</span><span class="s2">instanceMethodForSelector</span>:<span class="s1">@selector</span>(componentsSeparatedByString:)];

<span class="s2">class_replaceMethod</span>([<span class="s2">NSString</span><span class="s2">class</span>],<span class="s1">@selector</span>(componentsSeparatedByString:), (<span class="s1">IMP</span>)<span class="s5">CustomComponentsSeparatedByString</span>,<span class="s7">"@@:@"</span>);

cFuncPointer2 = [NSStringinstanceMethodForSelector:@selector(isEqualToString:)];

<span class="s2">class_replaceMethod</span>([<span class="s2">NSString</span><span class="s2">class</span>],<span class="s1">@selector</span>(isEqualToString:), (<span class="s1">IMP</span>)<span class="s5">CustomIsEqualToString</span>,<span class="s7">"B@:@"</span>);

}

14、**自动序列化(转)**

#import “NSObject+AutoEncodeDecode.h”

@implementation NSObject (AutoEncodeDecode)

  • (void)encodeWithCoder:(NSCoder *)encoder {

    Class cls = [selfclass];

    while (cls != [NSObjectclass]) {

    <span class="s2">unsigned</span> <span class="s2">int</span> numberOfIvars =<span class="s4">0</span>;
    
    <span class="s3">Ivar</span>* ivars = <span class="s3">class_copyIvarList</span>(cls, &amp;numberOfIvars);
    
    <span class="s2">for</span>(<span class="s2">const</span> <span class="s3">Ivar</span>* p = ivars; p &lt; ivars+numberOfIvars; p++){
    
        <span class="s3">Ivar</span> <span class="s2">const</span> ivar = *p;
    
        <span class="s2">const</span> <span class="s2">char</span> *type =<span class="s3">ivar_getTypeEncoding</span>(ivar);

NSString *key = [NSStringstringWithUTF8String:ivar_getName(ivar)];

        <span class="s2">id</span> value = [<span class="s2">self</span><span class="s3">valueForKey</span>:key];

        <span class="s2">if</span> (value) {

            <span class="s2">switch</span> (type[<span class="s4">0</span>]) {

                <span class="s2">case</span> <span class="s1">_C_STRUCT_B</span>: {

                    <span class="s3">NSUInteger</span> ivarSize =<span class="s4">0</span>;

                    <span class="s3">NSUInteger</span> ivarAlignment =<span class="s4">0</span>;

                    <span class="s3">NSGetSizeAndAlignment</span>(type, &amp;ivarSize, &amp;ivarAlignment);

                    <span class="s3">NSData</span> *data = [<span class="s3">NSData</span><span class="s3">dataWithBytes</span>:(<span class="s2">const</span><span class="s2">char</span> *)<span class="s2">self</span> + <span class="s3">ivar_getOffset</span>(ivar)

                                                  <span class="s3">length</span>:ivarSize];

                    [encoder <span class="s3">encodeObject</span>:data<span class="s3">forKey</span>:key];

                }

                    <span class="s2">break</span>;

                <span class="s2">default</span>:

                    [encoder <span class="s3">encodeObject</span>:value

                                   <span class="s3">forKey</span>:key];

                    <span class="s2">break</span>;

            }

        }

    }

    <span class="s3">free</span>(ivars);

    cls = <span class="s3">class_getSuperclass</span>(cls);

}

}

  • (id)initWithCoder:(NSCoder *)decoder {

    self = [self init];

    if (self) {

    <span class="s3">Class</span> cls = [<span class="s2">self</span><span class="s3">class</span>];
    
    <span class="s2">while</span> (cls != [<span class="s3">NSObject</span><span class="s3">class</span>]) {
    
        <span class="s2">unsigned</span> <span class="s2">int</span> numberOfIvars =<span class="s4">0</span>;
    
        <span class="s3">Ivar</span>* ivars = <span class="s3">class_copyIvarList</span>(cls, &amp;numberOfIvars);
    
        <span class="s2">for</span>(<span class="s2">const</span><span class="s3">Ivar</span>* p = ivars; p &lt; ivars+numberOfIvars; p++){
    
            <span class="s3">Ivar</span> <span class="s2">const</span> ivar = *p;
    
            <span class="s2">const</span> <span class="s2">char</span> *type =<span class="s3">ivar_getTypeEncoding</span>(ivar);

NSString *key = [NSStringstringWithUTF8String:ivar_getName(ivar)];

            <span class="s2">id</span> value = [decoder <span class="s3">decodeObjectForKey</span>:key];

            <span class="s2">if</span> (value) {

                <span class="s2">switch</span> (type[<span class="s4">0</span>]) {

                    <span class="s2">case</span> <span class="s1">_C_STRUCT_B</span>: {

                        <span class="s3">NSUInteger</span> ivarSize =<span class="s4">0</span>;

                        <span class="s3">NSUInteger</span> ivarAlignment =<span class="s4">0</span>;

                        <span class="s3">NSGetSizeAndAlignment</span>(type, &amp;ivarSize, &amp;ivarAlignment);

                        <span class="s3">NSData</span> *data = [decoder<span class="s3">decodeObjectForKey</span>:key];

                        <span class="s2">char</span> *sourceIvarLocation = (<span class="s2">char</span>*)<span class="s2">self</span>+<span class="s3">ivar_getOffset</span>(ivar);

                        [data <span class="s3">getBytes</span>:sourceIvarLocation<span class="s3">length</span>:ivarSize];

                    }

                        <span class="s2">break</span>;

                    <span class="s2">default</span>:

                        [<span class="s2">self</span> <span class="s3">setValue</span>:[decoder <span class="s3">decodeObjectForKey</span>:key]

                                <span class="s3">forKey</span>:key];

                        <span class="s2">break</span>;

                }

            }

        }

        <span class="s3">free</span>(ivars);

        cls = <span class="s3">class_getSuperclass</span>(cls);

    }

}

return self;

}

 

Share Comments