Domanda

Sembra sicuramente abbastanza innocuo. Nel mio delegato app, controllo NSUserDefaults per un flag che mostri suggerimenti all'avvio. Se impostato, alla fine di applicationDidFinishLaunching: , faccio questo:

TipsViewController *vc = [[TipsViewController alloc]
  initWithNibName:@“TipsView" bundle:nil];
[window addSubview:vc.view];
[vc release];

L'idea è di mostrare temporaneamente questa vista. (Nota che non è un VC modale. Nessun controller di navigazione a questo punto, in più non c'è comunque barra di navigazione in questa vista.)

Una volta ignorata questa vista, aggiungeremo la nostra vista UITabBarController anticipata alla finestra e passeremo ad essa, quindi rimuovere la vista della punta dalla finestra principale. Non sono ancora arrivato al punto di vista del licenziamento perché, beh, continua a leggere.

Il VC di My TipsView è collegato più o meno in questo modo:

UIView -> view -> File’s Owner (TipsViewController)
  UIImageView -> background image
  UIView -> tipView -> File’s Owner
    UIImageView -> background image
    UIScrollView
      UILabel (tip text)
    UIButton -> touch-up-inside -> -(IBAction)button1:
    UIButton -> touch-up-inside -> -(IBAction)button2:
    UIButton -> touch-up-inside -> -(IBAction)button3:

La fonte contiene dichiarazioni e definizioni per tutte e tre le chiamate IBAction . In questo momento due di loro non fanno nulla. Il terzo cambia il suggerimento text , lo ridimensiona per adattarlo e regola il contentSize della vista di scorrimento in modo che corrisponda.

Quando eseguo l'app, la vista TipsViewController appare bene. Posso anche scorrere il testo del suggerimento. Tuttavia, quando innesco un ritocco interno su qualsiasi UIButton , Xcode inizia a piantarmi nella sorgente (dove ho posizionato un punto di interruzione in ogni IBAction ) ... e poi esce con EXC_BAD_ACCESS o obj_stack_overflow .

Ho confrontato questo con altre parti dell'app in cui ho un VC, una vista e pulsanti. È identico sotto tutti gli aspetti, tranne che, in questo caso, ho aggiunto una vista VC come sottoview della finestra dell'app invece di spingere il VC su un controller di navigazione . Inoltre, i documenti Visualizza la guida alla programmazione del controller per iPhone OS dicono che questo è un gioco equo:

  

Se si utilizza un controller a vista singola in   la tua applicazione, aggiungi la sua vista a   una finestra invece di aggiungere la vista   controller su una barra delle schede o navigazione   controller.

Vero, devo avere un UITabBarController in attesa dietro le quinte, e contiene schede con UINavigationControllers (e altri VC). Tuttavia, se viene visualizzata la vista del suggerimento, la vista del controller della barra delle schede ha non ancora aggiunto alla finestra. L'intento è scambiarlo dopo che abbiamo finito di mostrare i suggerimenti. In altre parole, a tutti gli effetti, agiamo temporaneamente come se avessimo un singolo VC in gioco. Successivamente, passiamo alla barra delle schede e abbattiamo la punta VC.

Forse sto facendo qualcosa di sottilmente sbagliato? Esiste un modo migliore? ("Deve esserci un modo migliore!")

Traccia dello stack di esempio:

#0  0x992b6f52 in objc_exception_throw
#1  0x302d6ffb in -[NSObject doesNotRecognizeSelector:]
#2  0x3026e056 in ___forwarding___
#3  0x3024a0a2 in __forwarding_prep_0___
#4  0x308f79d1 in -[UIApplication sendAction:to:from:forEvent:]
#5  0x309598b1 in -[UIControl sendAction:to:forEvent:]
#6  0x3095bad2 in -[UIControl(Internal) _sendActionsForEvents:withEvent:]
#7  0x3095a81e in -[UIControl touchesEnded:withEvent:]
#8  0x30910fdf in -[UIWindow _sendTouchesForEvent:]
#9  0x308faecb in -[UIApplication sendEvent:]
#10 0x309013e1 in _UIApplicationHandleEvent
#11 0x32046375 in PurpleEventCallback
#12 0x30245560 in CFRunLoopRunSpecific
#13 0x30244628 in CFRunLoopRunInMode
#14 0x32044c31 in GSEventRunModal
#15 0x32044cf6 in GSEventRun
#16 0x309021ee in UIApplicationMain
#17 0x00002888 in main at main.m:14

Come puoi vedere dalla traccia, finiamo in doesNotRecognizeSelector: ... tranne che posso vedere chiaramente i metodi nella mia fonte VC tip. Inoltre, sono tutti cablati. (Nessun cablaggio multiplo o qualcosa del genere in IB. Tutto sembra a posto lì, fino alle relazioni con il proprietario del file.)

Indizi benvenuti / apprezzati!

È stato utile?

Soluzione

Il problema è proprio lì nel tuo primo frammento di codice: stai creando un'istanza di TipsViewController, conservandone la vista, quindi rilasciando il controller della vista, che causerà la sua deallocazione. Quindi ora il target dei pulsanti è un puntatore al controller di vista deallocato.

Una vista non mantiene il suo controller di vista, né conserva i propri delegati o destinazioni.

Dovrai mantenere l'istanza del controller di visualizzazione mantenuta & # 8212; forse in una proprietà conserva & # 8212; per tutto il tempo in cui desideri che la visualizzazione venga visualizzata. Al termine, è possibile rimuoverlo dalla vista principale e rilasciare il controller di visualizzazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top