NSMethodSignature和NSInvocation的用法

[plain]  view plain copy
  1.   
NSMethodSignature顾名思义应该就是“方法签名”,类似于C++中的编译器时的函数签名。
官方定义该类为对方法的参数、返回类似进行封装,协同NSInvocation实现消息转发。
通过消息转发可以用B实现A的方法。也是一种多重继承的解决方法。
<p style="margin-top: 0px; margin-bottom: 10px; padding-top: 0px; padding-bottom: 0px;"><span class="kwd" style="color: rgb(0, 0, 136);">interface</span><span class="pln"> </span><span class="typ" style="color: rgb(102, 0, 102);">LOCBird</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln"> </span><span class="typ" style="color: rgb(102, 0, 102);">NSObject</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span>
<span class="pln"> </span><span class="typ" style="color: rgb(102, 0, 102);">NSString</span><span class="pun" style="color: rgb(102, 102, 0);">*</span><span class="pln"> name_</span><span class="pun" style="color: rgb(102, 102, 0);">;</span>
<span class="pln">    </span>
<span class="pun" style="color: rgb(102, 102, 0);">}</span>
<span class="lit" style="color: rgb(0, 102, 102);">@end</span>


<span class="lit" style="color: rgb(0, 102, 102);">@implementation</span><span class="pln"> </span><span class="typ" style="color: rgb(102, 0, 102);">LOCBird</span>

<span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln">id</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln">init</span>
<span class="pun" style="color: rgb(102, 102, 0);">{</span>
<span class="pln"> </span><span class="kwd" style="color: rgb(0, 0, 136);">self</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="kwd" style="color: rgb(0, 0, 136);">super</span><span class="pln"> init</span><span class="pun" style="color: rgb(102, 102, 0);">];</span>
<span class="pln"> </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">self</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span>
<span class="pln">  name_ </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">[[</span><span class="typ" style="color: rgb(102, 0, 102);">NSString</span><span class="pln"> alloc</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln"> initWithString</span><span class="pun" style="color: rgb(102, 102, 0);">:@</span><span class="str" style="color: rgb(0, 136, 0);">"I am a Bird!!"</span><span class="pun" style="color: rgb(102, 102, 0);">];</span>
<span class="pln">  </span>
<span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">}</span>
<span class="pln"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln"> </span><span class="kwd" style="color: rgb(0, 0, 136);">self</span><span class="pun" style="color: rgb(102, 102, 0);">;</span>
<span class="pun" style="color: rgb(102, 102, 0);">}</span>

<span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">void</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln">dealloc</span>
<span class="pun" style="color: rgb(102, 102, 0);">{</span>
<span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">name_ release</span><span class="pun" style="color: rgb(102, 102, 0);">];</span>
<span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="kwd" style="color: rgb(0, 0, 136);">super</span><span class="pln"> dealloc</span><span class="pun" style="color: rgb(102, 102, 0);">];</span>
<span class="pun" style="color: rgb(102, 102, 0);">}</span>

<span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="typ" style="color: rgb(102, 0, 102);">NSMethodSignature</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">*)</span><span class="pln">methodSignatureForSelector</span><span class="pun" style="color: rgb(102, 102, 0);">:(</span><span class="pln">SEL</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln">aSelector</span>
<span class="pun" style="color: rgb(102, 102, 0);">{</span>
<span class="pln"> </span><span class="typ" style="color: rgb(102, 0, 102);">NSMethodSignature</span><span class="pun" style="color: rgb(102, 102, 0);">*</span><span class="pln"> signature </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="kwd" style="color: rgb(0, 0, 136);">super</span><span class="pln"> methodSignatureForSelector</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln">aSelector</span><span class="pun" style="color: rgb(102, 102, 0);">];</span>
<span class="pln"> </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln">signature</span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="kwd" style="color: rgb(0, 0, 136);">nil</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span>
<span class="pln">  signature </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">name_ methodSignatureForSelector</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln">aSelector</span><span class="pun" style="color: rgb(102, 102, 0);">];</span>
<span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">}</span>
<span class="pln"> </span><span class="typ" style="color: rgb(102, 0, 102);">NSUInteger</span><span class="pln"> argCount </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">signature numberOfArguments</span><span class="pun" style="color: rgb(102, 102, 0);">];</span>
<span class="pln"> </span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="typ" style="color: rgb(102, 0, 102);">NSInteger</span><span class="pln"> i</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln"> i</span><span class="pun" style="color: rgb(102, 102, 0);"><</span><span class="pln">argCount </span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln"> i</span><span class="pun" style="color: rgb(102, 102, 0);">++)</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span>
<span class="pln">  </span><span class="typ" style="color: rgb(102, 0, 102);">NSLog</span><span class="pun" style="color: rgb(102, 102, 0);">(@</span><span class="str" style="color: rgb(0, 136, 0);">"%s"</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">signature getArgumentTypeAtIndex</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln">i</span><span class="pun" style="color: rgb(102, 102, 0);">]);</span>
<span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">}</span>
<span class="pln"> </span><span class="typ" style="color: rgb(102, 0, 102);">NSLog</span><span class="pun" style="color: rgb(102, 102, 0);">(@</span><span class="str" style="color: rgb(0, 136, 0);">"returnType:%s ,returnLen:%d"</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">signature methodReturnType</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">signature methodReturnLength</span><span class="pun" style="color: rgb(102, 102, 0);">]);</span>
<span class="pln"> </span><span class="typ" style="color: rgb(102, 0, 102);">NSLog</span><span class="pun" style="color: rgb(102, 102, 0);">(@</span><span class="str" style="color: rgb(0, 136, 0);">"signature:%@"</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln"> signature</span><span class="pun" style="color: rgb(102, 102, 0);">);</span>
<span class="pln"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln"> signature</span><span class="pun" style="color: rgb(102, 102, 0);">;</span>
<span class="pun" style="color: rgb(102, 102, 0);">}</span>

<span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">void</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln">forwardInvocation</span><span class="pun" style="color: rgb(102, 102, 0);">:(</span><span class="typ" style="color: rgb(102, 0, 102);">NSInvocation</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">*)</span><span class="pln">anInvocation</span>
<span class="pun" style="color: rgb(102, 102, 0);">{</span>
<span class="pln"> </span><span class="typ" style="color: rgb(102, 0, 102);">NSLog</span><span class="pun" style="color: rgb(102, 102, 0);">(@</span><span class="str" style="color: rgb(0, 136, 0);">"forwardInvocation:%@"</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln"> anInvocation</span><span class="pun" style="color: rgb(102, 102, 0);">);</span>
<span class="pln"> SEL seletor </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">anInvocation selector</span><span class="pun" style="color: rgb(102, 102, 0);">];</span>
<span class="pln"> </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">([</span><span class="pln">name_ respondsToSelector</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln">seletor</span><span class="pun" style="color: rgb(102, 102, 0);">])</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span>
<span class="pln">  </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">anInvocation invokeWithTarget</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln">name_</span><span class="pun" style="color: rgb(102, 102, 0);">];</span>
<span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">}</span>
<span class="pln"> </span>
<span class="pun" style="color: rgb(102, 102, 0);">}</span>

<span class="lit" style="color: rgb(0, 102, 102);">@end</span></p><p style="margin-top: 0px; margin-bottom: 10px; padding-top: 0px; padding-bottom: 0px;">
</p><p style="margin-top: 0px; margin-bottom: 10px; padding-top: 0px; padding-bottom: 0px;"><span class="com" style="color: rgb(136, 0, 0);">//调用</span></p><p style="margin-top: 0px; margin-bottom: 10px; padding-top: 0px; padding-bottom: 0px;"><span class="com" style="color: rgb(136, 0, 0);"> id bird = [[LOCBird alloc] init];</span>
<span class="pln"> </span><span class="typ" style="color: rgb(102, 0, 102);">NSLog</span><span class="pun" style="color: rgb(102, 102, 0);">(@</span><span class="str" style="color: rgb(0, 136, 0);">"len= %d"</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">bird length</span><span class="pun" style="color: rgb(102, 102, 0);">]);</span></p>
输出 参考
表 6-1  Objective-C类型编码

编码

含义

c

char

i

int

s

short

l

long

在64位程序中,l为32位。

q

long long

C

unsigned char

I

unsigned int

S

unsigned short

L

unsigned long

Q

unsigned long long

f

float

d

double

B

C++标准的bool或者C99标准的_Bool

v

void

*

字符串(char *

@

对象(无论是静态指定的还是通过id引用的)

#

类(Class

:

方法选标(SEL)

[array type]

数组

{name=type...}

结构体

(name=type...)

联合体

bnum

num个bit的位域

^type

type类型的指针

?

未知类型(其它时候,一般用来指函数指针)

使用方法
<p style="margin-top: 0px; margin-bottom: 10px; padding-top: 0px; padding-bottom: 0px;"><span class="pun" style="color: rgb(102, 102, 0);">-(</span><span class="kwd" style="color: rgb(0, 0, 136);">void</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln"> initWithTarget</span><span class="pun" style="color: rgb(102, 102, 0);">:(</span><span class="pln">id</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln"> rec selector</span><span class="pun" style="color: rgb(102, 102, 0);">:(</span><span class="pln">SEL</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln"> cb</span><span class="pun" style="color: rgb(102, 102, 0);">{</span>
<span class="pln">    anchorPoint_ </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln"> ccp</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="lit" style="color: rgb(0, 102, 102);">0.5f</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln"> </span><span class="lit" style="color: rgb(0, 102, 102);">0.5f</span><span class="pun" style="color: rgb(102, 102, 0);">);</span>
<span class="pln">    </span><span class="typ" style="color: rgb(102, 0, 102);">NSMethodSignature</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">*</span><span class="pln"> sig </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln"> </span><span class="kwd" style="color: rgb(0, 0, 136);">nil</span><span class="pun" style="color: rgb(102, 102, 0);">;</span>
<span class="pln">    </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln"> rec </span><span class="pun" style="color: rgb(102, 102, 0);">&&</span><span class="pln"> cb </span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span>
<span class="pln">        sig </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">rec methodSignatureForSelector</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln">cb</span><span class="pun" style="color: rgb(102, 102, 0);">];</span>
<span class="pln">        invocation </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln"> </span><span class="kwd" style="color: rgb(0, 0, 136);">nil</span><span class="pun" style="color: rgb(102, 102, 0);">;</span>
<span class="pln">        invocation </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="typ" style="color: rgb(102, 0, 102);">NSInvocation</span><span class="pln"> invocationWithMethodSignature</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln">sig</span><span class="pun" style="color: rgb(102, 102, 0);">];</span>
<span class="pln">        </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">invocation setTarget</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln">rec</span><span class="pun" style="color: rgb(102, 102, 0);">];</span>
<span class="pln">        </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">invocation setSelector</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln">cb</span><span class="pun" style="color: rgb(102, 102, 0);">];</span>
<span class="pln">        </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">invocation setArgument</span><span class="pun" style="color: rgb(102, 102, 0);">:&</span><span class="kwd" style="color: rgb(0, 0, 136);">self</span><span class="pln"> atIndex</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">];</span>
<span class="pln">        </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">invocation retain</span><span class="pun" style="color: rgb(102, 102, 0);">];</span>
<span class="pln">    </span><span class="pun" style="color: rgb(102, 102, 0);">}</span>
<span class="pun" style="color: rgb(102, 102, 0);">}</span></p>
[invocation invoke ];是调用SEL。上述第二个参数为自身。


NSMethodSignature和 NSInvocation实现编码
[plain]  view plain copy
  1. - (void)encodeWithCoder:(NSCoder *)encoder{  
  2.     NSDictionary *attrDic = [self getKeyAndObjectForDictionry];  
  3.     if (attrDic == nil) {  
  4.         return;  
  5.     }  
  6.     NSEnumerator *keyEnum = [attrDic keyEnumerator];  
  7.     id attributeName;  
  8.     while ((attributeName = [keyEnum nextObject])) {  
  9.         SEL getSel = NSSelectorFromString(attributeName);  
  10.         if ([self respondsToSelector:getSel]) {  
  11.             NSMethodSignature *signature = nil;  
  12.             signature = [self methodSignatureForSelector:getSel];  
  13.             NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];  
  14.             [invocation setTarget:self];  
  15.             [invocation setSelector:getSel];  
  16.             NSObject *valueObj = nil;  
  17.             [invocation invoke];  
  18.             [invocation getReturnValue:&valueObj];  
  19.               
  20.             if (valueObj) {  
  21.                 [encoder encodeObject:valueObj forKey:attributeName];  
  22.             }  
  23.         }  
  24.     }  
  25. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值