Мне нужна твоя помощь. У меня есть некоторые проблемы с 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;
//---------------------------
Вывод NSLog: sizeof (UIButton) = 140, sizeof (результат) = 4, методturnlelength = 4, sizeof (* результат) = 1
Проблема в том, что значение из NSInvocation является указателем размера 4 байта. Он должен указывать на объект UIButton размером 140 байт. Но на самом деле относится к 1-байтовым данным. Так что же происходит с объектом UIButton, который должен быть инициализирован с помощью 'buttonWithType:'?
Добавлено после получения некоторых ответов:
Чтобы уточнить: я хочу получить UIButton
объект, но после этого кода id pushButton5 = (id) result;
, когда я пытаюсь работать с pushButton5
, он вызывает EXC_BAD_ACCESS
. Кто-нибудь может мне помочь?
Может ли это произойти из-за этого?
Class cls = NSClassFromString(@"UIButton");
...
[anInvocationTMP setTarget:cls];
Это правильно, не правда ли?