Domanda Come scoprire chi ha chiamato un metodo?


Esempio: quando viene chiamato il mio metodo -fooBar, voglio che acceda alla console quale altro metodo di cui l'altra classe lo ha chiamato.

In questo momento, so solo come registrare il nome del metodo di fooBar stesso ed è classe, con questo:

_cmd

[self class]

È possibile capire?


11
2017-11-25 00:51


origine


risposte:


Nel codice completamente ottimizzato, non esiste un metodo sicuro al 100% per determinare il chiamante su un determinato metodo. Il compilatore può impiegare un'ottica di coda, mentre il compilatore riutilizza efficacemente lo stack frame del chiamante per il callee.

Per vedere un esempio di questo, imposta un punto di interruzione su qualsiasi metodo dato usando gdb e guarda il backtrace. Nota che non vedi objc_msgSend () prima di ogni chiamata di metodo. Questo perché objc_msgSend () fa una coda per l'implementazione di ciascun metodo.

Sebbene sia possibile compilare l'applicazione non ottimizzata, occorrono versioni non ottimizzate di tutte le librerie di sistema per evitare solo questo problema.

E questo è solo un problema; in effetti, stai chiedendo "come faccio a reinventare CrashTracer o gdb?". Un problema molto difficile su cui sono fatte le carriere. A meno che tu non voglia che gli "strumenti di debug" siano la tua carriera, ti consiglierei di non seguire questa strada.

A quale domanda stai veramente cercando di rispondere?


36
2017-11-25 01:07



Che ne dite di Questo:

NSString *sourceString = [[NSThread callStackSymbols] objectAtIndex:1];

NSCharacterSet *separatorSet = [NSCharacterSet characterSetWithCharactersInString:@" -[]+?.,"];
NSMutableArray *array = [NSMutableArray arrayWithArray:[sourceString  componentsSeparatedByCharactersInSet:separatorSet]];
[array removeObject:@""];

NSLog(@"Class caller = %@", [array objectAtIndex:3]);
NSLog(@"Method caller = %@", [array objectAtIndex:4]);

Crediti all'autore originale, intropedro.


6
2018-02-06 19:31



Non è possibile nel caso generale senza realmente camminare nello stack. Non c'è nemmeno la garanzia che un altro oggetto invii il messaggio che ha chiamato il metodo. Ad esempio, potrebbe essere chiamato da un blocco in un gestore di segnale.


3
2017-11-25 00:54



Vedere backtrace (3).


2
2017-11-25 02:19



Utente il seguente metodo
Passare l'indice per il quale si desidera visualizzare il metodo e passare -1 se si desidera visualizzare lo stack completo del metodo

+(void) methodAtIndex:(int)index{
    void* callstack[128];
    int frames = backtrace(callstack, 128);
    char** strs = backtrace_symbols(callstack, frames);

    if (index == -1) {
        for (int i = 0; i < frames; ++i) {
            printf("%s\n", strs[i]);
        }
    }
    else {
        if (index < frames) {
            printf("%s\n", strs[index]);
        }
    }
    free(strs);

}

2
2017-09-04 13:27



NSLog(@"Show stack trace: %@", [NSThread callStackSymbols]);

2
2017-08-25 10:18



Questa informazione può essere ottenuta usando DTrace.


1
2017-11-25 01:03



Crea una macro che aggiunge il __FUNCTION__ al nome della funzione alla chiamata di funzione. Questa macro chiamerà la tua funzione con un parametro aggiuntivo di un carattere * per la funzione di destinazione.


1
2017-11-25 01:04



Stavo cercando di capire chi, come e quando cambia le dimensioni della finestra e ha fatto un po 'di lavoro manuale:

- (void)logWindowWidth:(NSString *)whoCalls {
   NSLog(@"%@", whoCalls);
   NSLog(@"self.window.size.width %f", self.window.size.width);
}

-(void)someMethod {
  [self logWindowWidth:@"someMethod - before"];
  ...
  [self logWindowWidth:@"someMethod - after"];
}

-(void)anotherMethod {
  [self logWindowWidth:@"anotherMethod - before"];
  ...
  [self logWindowWidth:@"anotherMethod - after"];
}

0
2018-02-04 14:05