2013-03-18 6 views
8

Un'applicazione di elaborazione immagini è veloce sul simulatore, ma è molto lenta su un dispositivo reale (iPhone 4GS).iOS e Objective-C: la maggior parte del tempo di CPU viene speso in [NSObject release] e [NSObject retain], ma il metodo di classe non esegue alcuna operazione di memoria

Quando si esegue l'applicazione in "strumenti", compaiono i seguenti albero chiamata:

enter image description here

Nota che le chiamate all'interno del cerchio rosso sono segnalati per prendere quasi tutto il tempo di CPU del metodo .

Il metodo in questione è un metodo di classe (non un metodo di istanza), con il seguente codice:

@implementation Line2F 

+ (CGFloat)signTested:(Point2F *)tested p1:(Point2F *)p1 p2:(Point2F *)p2 
{ 
    return [Line2F signTestedX:tested.x testedY:tested.y 
          p1x:p1.x p1y:p1.y 
          p2x:p2.x p2y:p2.y]; 
} 

+ (CGFloat)signTestedX:(CGFloat)testedX testedY:(CGFloat)testedY 
        p1x:(CGFloat)p1x p1y:(CGFloat)p1y 
        p2x:(CGFloat)p2x p2y:(CGFloat)p2y 
{ 
    return (testedX - p2x) * (p1y - p2y) - (p1x - p2x) * (testedY - p2y); 
} 

@end 

Qualcuno può spiegare perché è la maggior parte del tempo di CPU viene speso per [NSObject release] e [NSObject retain]?

risposta

3

Se non lo sa, ARC conserva tutti gli argomenti su un metodo e li rilascia quando termina il metodo (vedere this objc-language mailing list email).

Si dovrebbe essere in grado di evitarlo annotando gli argomenti a +signTested:p1:p2: con __weak o __unsafe_unretained, secondo le proprie esigenze.

+3

Il problema non è in '+ signTestedX: testedYY: p1x: p1y: p2x: p2y:' che accetta gli argomenti di CGFloat; come noti che i float non sono oggetti e la semantica non avrebbe senso. Il problema è in '+ signTested: p1: p2:' che chiama attraverso '+ signTestedX: testedYY: p1x: p1y: p2x: p2y:' e prende gli argomenti 'Point2F' che (appare) sono oggetti che possono essere mantenuti/rilasciato. – frozendevil

+1

passando una direttiva __weak ha ancora qualche elaborazione ARC ma è più veloce. L'unico modo che ho trovato per rimuovere completamente è passando semplicemente CGFloat invece di oggetti. – Guy

1

Beh, potrebbe essere un sacco di roba. Come dice FrozenDevil, potrebbe essere collegato ad ARC se lo stai usando. Immagino che molto probabilmente il metodo si chiami diverse volte all'interno di un enorme loop. Cerca di trasmettere riferimenti deboli, ma ovviamente devi essere sicuro che esistano per l'intero processo. Vorrei provare anche a ottimizzare il ciclo che incorpora ogni ciclo in un pool di autorelease.