2013-07-10 5 views
14

Ci sono elementi come UITableView s, UINavigationBar s che hanno uno stile diverso su iOS 7.In che modo iOS 7 implementa gli elementi dell'interfaccia utente in modo che risultino diversi a seconda dell'SDK con cui vengono compilati?

Questo stile è determinato in fase di esecuzione, dal momento che tali classi sono implementati su UIKit, e UIKit è collegata con l'applicazione dinamicamente a runtime , non staticamente al momento della compilazione.

Quindi si potrebbe pensare che qualsiasi app venga eseguita su iOS 7 avrebbe quegli elementi come sembrano su iOS 7. Tuttavia, mantengono lo stesso stile usato su iOS 6, fino a quando non si compila con iOS 7 SDK. Fatta eccezione per alcuni di essi (come UIAlertView o UIMenuController)

mia unica spiegazione per questo è che fanno qualcosa di un po 'come questo:

#define SDKApplicationWasLinkedAgainst ... 
if (SDKApplicationWasLinkedAgainst < 7.0) 
    ... 
else 
    ... 

Questo è ovviamente molto ingombrante, perché hanno bisogno di mantenere il mantenimento di un sacco di vecchio codice. Quindi sono curioso, è davvero questo che sta succedendo sotto il cofano? Cosa mi manca?

+5

@Unicorn: È vero, tuttavia non sta chiedendo nulla di specifico per iOS 7 che sarà coperto dalla NDA. Questa domanda potrebbe essere applicata a ** qualsiasi ** due versioni di iOS. – lnafziger

+2

Sfortunatamente, a meno che tu non sia un programmatore di Apple, non puoi davvero rispondere alla domanda su come ** Apple ** lo fa. Potresti avere qualche idea su * un modo * che ** tu ** potresti farlo se ripeti la tua domanda. – lnafziger

+2

In realtà si può rispondere a questa domanda anche se non si lavora in Apple, e non sarà un'opinione: un mio college ha scoperto come lo fanno facendo un po 'di smontaggio. –

risposta

9

Senza entrare troppo nel territorio NDA'd, vorrei solo affermare che sì, essi sono conditionalizing aspetto e il comportamento in base al largo del risultato del seguente invito:

_UIApplicationUsesLegacyUI() 

Questa funzione, a sua volta, effettua una chiamata a GSApplicationUsesLegacyUI(), che presumo restituisca un risultato basato sulla versione dell'UIKit collegata.

Ciò significa che sì, stanno condizionando parti di UIKit per eredità. Non sono sicuro che sia una buona cosa, ma è quello che hanno deciso di fare.

-1

Non posso esserne certo, ma questa è una supposizione su come è fatta. Poiché sanno a quale versione dell'SDK è collegata la tua app, rilasciano la versione su dispositivi iOS 7. Quindi c'è una gerarchia sul filesystem lungo le linee di /.../iPhoneOS6.1.sdk/.../Frameworks/UIKit. Quindi, quando carica la tua app, può semplicemente impostare il percorso di ricerca per le librerie in modo che facciano riferimento a qualsiasi SDK a cui è stata collegata la tua app.

Ecco come Xcode lo fa proprio ora. All'interno della directory Developer all'interno del pacchetto Xcode c'è una directory SDK, che a sua volta contiene tutti i diversi SDK da collegare.

+0

Sembra una possibile idea, ma non può essere perché ci sono alcune cose che sembrano diverse. Come 'UIActionSheet',' UIAlertView', 'UIMenuController' ... –

+0

In tal caso, i dispositivi iOS 7 potrebbero aggiornare l'aspetto dei precedenti SDK. Non c'è nulla che dice che la versione del sistema operativo non può affatto aggiornare i vecchi SDK. In questo modo il sistema operativo può aggiornare l'SDK per le versioni minori (6.0.1, 6.0.2, ecc.) Senza dover ricollegare le app con le versioni più recenti dell'SDK. L'unico motivo per aggiornare a versioni più recenti dell'SDK (come 6.1) sarebbe utilizzare le nuove cose introdotte in quella versione. – Streeter

+0

Dubito davvero che sia quello che hanno fatto: P Ricompilare il vecchio SDK? Se quello che vogliono è la retrocompatibilità per non rompere le vecchie app che non ha senso. –

4

La mia scommessa è che usano framework compatibility versions.

Ogni volta che si compila la tua app, la tua app è collegata a un framework specifico, con la versione di compatibilità e la versione corrente. Puoi vedere quei numeri se esegui otool -L YourApp.app/YourApp. Ad esempio, per un'applicazione compilata po 'di tempo fa, ho ottenuto questo:

/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 751.58.0) 
/System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 1500.0.0) 

Come si può vedere il percorso completo del quadro UIKit viene memorizzato nel binario Mach-O, lungo un paio di versioni (e specialmente il versione che ho compilato contro in quel momento).

Suppongo che iOS 7 includa sia la versione UIKit inclusa: quella di iOS6 contrassegnata con la versione corrispondente che dice compatibilità da 1.0.0, sia quella di iOS7 contrassegnata come compatibile con qualcosa di superiore a 1500.0.0 (I non so se questo è il numero per iOS 6.1.3, ma ottieni l'idea).

Quando il binario iOS6 è caricato, le sue dipendenze della biblioteca sono letti da dyld e risolti, perché sono stati compilati dicendo current version 1500.0.0, e la libreria per iOS 7 dice compatibility version 1501.0.0, sarete collegati alla libreria per iOS 6.

dal momento che un quadro è anche un bundle, tutte le risorse sono perfettamente contenuti, e saranno utilizzati solo dalla versione giusta, ed è così che i diversi elementi visivi avrà un aspetto diverso se si compila contro iOS 6 SDK o iOS 7 SDK.

potrei sbagliarmi, ma ho semplicemente spero non usano la tecnica di codice si propone, perché sarà una base di codice di merda da mantenere.

+0

Non penso che iOS abbia versioni multiple dello stesso framework. Nel tuo esempio, la versione 1501.0.0 è retrocompatibile con la versione 1500.0.0. Ma come hai detto correttamente, il numero di versione a cui è stata collegata l'app è registrato nel file binario, in modo da poterlo verificare in fase di runtime. –

+0

Questo ancora non spiegherebbe perché certe classi hanno il nuovo aspetto (ad esempio 'UIAlertView') –

+0

@MartinR: è possibile verificare in fase di runtime, ma penso che i doppi binari siano facili da gestire. Se dovessi fare ciò che Apple deve fare durante i tempi di transizione, sceglierò di non eseguire tali controlli in runtime. – yonosoytu

Problemi correlati