6

Desidero utilizzare CFStreamCreatePairWithSocketToHost con NSInput - e OutputStream s. Ho due ivar NSInputStream *_inputStream e NSOutputStream *_outputStream.La trasmissione di un puntatore indiretto a un puntatore Objective-C a "CFReadStreamRef *" non è consentita con ARC

Di seguito mi dà due messaggi di errore:

CFStreamCreatePairWithSocketToHost(NULL, 
    (__bridge_retained CFStringRef)self.hostname, self.port, 
    (CFReadStreamRef *)&_inputStream, (CFWriteStreamRef *)&_outputStream); 

error: cast of an indirect pointer to an Objective-C pointer to ' CFReadStreamRef * ' (aka ' struct __CFReadStream ** ') is disallowed with ARC
error: cast of an indirect pointer to an Objective-C pointer to ' CFWriteStreamRef * ' (aka ' struct __CFWriteStream ** ') is disallowed with ARC

Come dovrei risolvere questo problema? Ho provato a utilizzare __bridge ma ho ricevuto messaggi di errore simili.

risposta

4

Passa un puntatore alle attuali variabili CFReadStreamRef e CFWriteStreamRef, quindi trasferisci quando si assegnano i tuoi NSTypes. In sostanza:

CFThingRef cfThing = NULL; 
CFFunctionGetThing(&cfThing); 
NSThing * nsThing = cfThing; 

Naturalmente, si dovrà aggiungere il cast ponte appropriato e fare tutte le opportune ops di conteggio di riferimento per cfThing.

+0

È questo l'unico modo per farlo? –

+0

@WTP Non sono sicuro: non ho passato molto tempo con ARC fino ad oggi. Avvolgilo! :) – justin

+0

@WTP: non dimenticare che la funzione eseguirà lo zapping del contenuto precedente di _inputStream e _outputStream con i suoi nuovi CRStreamRefs, quindi potresti anche renderli CFStreamRefs. – JeremyP

0

Pensa a cosa sta facendo ARC e cosa fanno i cast __bridge: ARC si assume la responsabilità di conservare/rilasciare NSObjects. __bridge trasferisce questa responsabilità. Ad esempio, __bridge_retained conserva una NSString, esegue il cast del puntatore su CFStringRef e ha ceduto la responsabilità di eseguire l'operazione di rilascio corrispondente a chiunque utilizzi CFStringRef.

Che il non possa funzionare con un puntatore a un NSObject * o un puntatore a un riferimento di Core Foundation. Un puntatore indica una posizione di memoria. È possibile archiviare qualsiasi tipo di oggetto NSObject * o Core Foundation.

Sono necessarie due variabili, una per un NSInputStream * e una per un CFReadStreamRef. Utilizzare il cast del bridge appropriato per spostare NSInputStream * su CFReadStreamRef. Ora hai ciò che vuoi e puoi passare l'indirizzo.