Como exatamente NSInvocation
funciona? Existe uma boa introdução?
Estou especificamente com problemas para entender como o código a seguir (da Cocoa Programming para Mac OS X, 3ª Edição ) funciona, mas também posso aplicar os conceitos independentemente do exemplo do tutorial. O código:
- (void)insertObject:(Person *)p inEmployeesAtIndex:(int)index
{
NSLog(@"adding %@ to %@", p, employees);
// Add inverse of this operation to undo stack
NSUndoManager *undo = [self undoManager];
[[undo prepareWithInvocationTarget:self] removeObjectFromEmployeesAtIndex:index];
if (![undo isUndoing])
[undo setActionName:@"Insert Person"];
// Finally, add person to the array
[employees insertObject:p atIndex:index];
}
- (void)removeObjectFromEmployeesAtIndex:(int)index
{
Person *p = [employees objectAtIndex:index];
NSLog(@"removing %@ from %@", p, employees);
// Add inverse of this operation to undo stack
NSUndoManager *undo = [self undoManager];
[[undo prepareWithInvocationTarget:self] insertObject:p
inEmployeesAtIndex:index];
if (![undo isUndoing])
[undo setActionName:@"Delete Person"];
// Finally, remove person from array
[employees removeObjectAtIndex:index];
}
Eu entendo o que está tentando fazer. (BTW, employees
é NSArray
de uma Person
classe personalizada .)
Sendo um cara do .NET, tento associar conceitos desconhecidos de Obj-C e Cocoa a conceitos do .NET aproximadamente análogos. Isso é semelhante ao conceito de delegado do .NET, mas não é tipado?
Isso não está 100% claro no livro, então estou procurando algo suplementar de verdadeiros especialistas em cacau / Obj-C, novamente com o objetivo de entender o conceito fundamental sob o exemplo simples (-ish). Estou realmente procurando poder aplicar o conhecimento de forma independente - até o capítulo 9, eu não estava tendo dificuldade em fazer isso. Mas agora ...
Desde já, obrigado!
fonte
setArgument:atIndex:
, para que a atribuição de arg seja realmente lida[myInvocation setArgument:&myString atIndex:2]
.Aqui está um exemplo simples de NSInvocation em ação:
Quando chamado -
[self hello:@"Hello" world:@"world"];
- o método irá:No final, você obterá uma impressão assim:
Obviamente, o objeto de destino
self
deve continuar existindo para o NSTimer enviar o NSInvocation para ele. Por exemplo, um objeto Singleton ou um AppDelegate que existe durante a duração do aplicativo.ATUALIZAR:
Como observado acima, quando você passa um NSInvocation como argumento para um NSTimer, o NSTimer retém automaticamente todos os argumentos do NSInvocation.
Se você não está passando um NSInvocation como argumento para um NSTimer e planeja mantê-lo por um tempo, chame o
-retainArguments
método Caso contrário, seus argumentos poderão ser desalocados antes que a chamada seja invocada, causando o travamento do seu código. Veja como fazê-lo:fonte
invocationWithMethodSignature:
inicializador seja usado, você ainda precise ligarsetSelector:
. Parece redundante, mas acabei de testar e é necessário.Você pode tentar usar a biblioteca aqui, que é muito melhor: http://cocoawithlove.com/2008/03/construct-nsinvocation-for-any-message.html
fonte
Eu construo um exemplo simples de chamar vários tipos de métodos com o NSInvocation.
Tive problemas ao chamar vários parâmetros usando obj_msgSend
https://github.com/clearbrian/NSInvocation_Runtime
fonte