Ale*_*der 3 pointers objective-c nsinvocation
我需要你的帮助.我在NSInvocation'getReturnValue:'方法中遇到了一些问题.我想以编程方式创建UIButton,甚至更多,我想使用NSInvocation动态创建它,并通过NSArray传递值(这就是我包装UIButtonTypeRoundedRect的原因).
清单.
NSLog(@"Button 4 pushed\n");//this code executed when button pushed
Class cls = NSClassFromString(@"UIButton");//if exists {define class},else cls=nil
SEL msel = @selector(buttonWithType:);
//id pushButton5 = [cls performSelector:msel withObject:UIButtonTypeRoundedRect];//this code works correctly,but I want to do this by NSInvocation
//---------------------------
NSMethodSignature *msignatureTMP;
NSInvocation *anInvocationTMP;
msignatureTMP = [cls methodSignatureForSelector:msel];
anInvocationTMP = [NSInvocation invocationWithMethodSignature:msignatureTMP];
[anInvocationTMP setTarget:cls];
[anInvocationTMP setSelector:msel];
UIButtonType uibt_ = UIButtonTypeRoundedRect;
NSNumber *uibt = [NSNumber numberWithUnsignedInt:uibt_];
NSArray *paramsTMP;
paramsTMP= [NSArray arrayWithObjects:uibt,nil];
id currentValTMP = [paramsTMP objectAtIndex:0];//getParam from NSArray
NSInteger i=2;
void* bufferTMP;
//if kind of NSValue unwrapp it.
if ([currentValTMP isKindOfClass:[NSValue class]]) {
NSUInteger bufferSize = 0;
NSGetSizeAndAlignment([currentValTMP objCType], &bufferSize, NULL);
bufferTMP = malloc(bufferSize);
[currentValTMP getValue:bufferTMP];//copy currentVal to bufer
[anInvocationTMP setArgument:bufferTMP atIndex:i];// The +2 represents the (self) and (cmd) offsets
}else {
[anInvocationTMP setArgument:¤tValTMP atIndex:i];//Again,+2 represents (self) and (cmd) offsets
}
void* result = malloc([[cls methodSignatureForSelector:msel] methodReturnLength]);
[anInvocationTMP invoke];
[anInvocationTMP getReturnValue:result];
NSLog(@"sizeof(UIButton)=%i,sizeof(result)=%i,methodreturnlength = %i,sizeof(*result)=%i",class_getInstanceSize(NSClassFromString(@"UIButton")),sizeof(result),[[cls methodSignatureForSelector:msel] methodReturnLength],sizeof(*result));
id pushButton5;
pushButton5=result;
//---------------------------
Run Code Online (Sandbox Code Playgroud)
NSLog输出:sizeof(UIButton)= 140,sizeof(result)= 4,methodreturnlength = 4,sizeof(*result)= 1
问题是来自NSInvocation的值是大小为4字节的指针.它应该指向UIButton对象,大小为140字节.但实际上是指1字节数据.那么UIButton对象会发生什么呢,应该用'buttonWithType:'来初始化?
澄清:我想得到UIButton对象,但在这段代码之后id pushButton5 = (id) result;,当我尝试使用时pushButton5,它会导致EXC_BAD_ACCESS.有人能帮我吗?
这可能因为这个而发生吗?
Class cls = NSClassFromString(@"UIButton");
...
[anInvocationTMP setTarget:cls];
Run Code Online (Sandbox Code Playgroud)
这是对的,不是吗?
sps*_*ley 18
如果您使用ARC,我会替换它:
void* result = malloc([[cls methodSignatureForSelector:msel] methodReturnLength]);
[anInvocationTMP invoke];
[anInvocationTMP getReturnValue:result];
Run Code Online (Sandbox Code Playgroud)
有了这个:
CFTypeRef result;
[anInvocationTMP invoke];
[anInvocationTMP getReturnValue:&result];
if (result)
CFRetain(result);
UIButton *pushButton5 = (__bridge_transfer UIButton *)result;
Run Code Online (Sandbox Code Playgroud)
原因是invokation的返回对象没有被保留,所以它会消失,即使你立即将它分配给一个对象引用,除非你先保留它然后告诉ARC转移所有权.
| 归档时间: |
|
| 查看次数: |
4385 次 |
| 最近记录: |