2012-02-02 1 views
28

È possibile definire una proprietà del blocco Objective-C ma avere ancora il completamento del codice completo in Xcode 4?Proprietà del blocco Objective-C con il completamento del codice Xcode

Se uso un typedef per definire il blocco:

typedef void (^CompletionBlock)(MyObject *myObj);

e quindi definire la proprietà:

@property (nonatomic, copy) CompletionBlock completionBlock;

e poi @synthesize la proprietà non ho ricevuto il codice completo completamento quando si chiama il setter. Xcode utilizzerà typedef e, a causa di ciò, il completamento del codice non utilizza la sintassi completa del blocco completa con i parametri del blocco, utilizza typedef.

Se definisco un metodo prototipo nell'intestazione che utilizza la sintassi del blocco completo invece del typedef:

@property (nonatomic, copy) void (^completionBlock)(MyObject *myObj);

e poi uso @synthesize, il setter fornito si avvicina utilizzando il completamento del codice completo sintassi ma cruciale lascia fuori i nomi dei parametri:

[self setCompletionBlock:(void (^)(MyObject *)) { ... }

Infine, se cerco di @synthesize e quindi ignorare l'attuazione setter o mettere il prototipo nell'intestazione:

- (void)setCompletionBlock:(void (^)(MyObject *myObj))completionBlock {...}

Un avviso viene sollevato affermando che il tipo di proprietà non corrisponde al tipo di accesso. Non importa quanto cerco di sintetizzare la sintassi, non sono in grado sia di definire una proprietà di blocco che un setter che abbia la sintassi completa per il completamento del codice. Posso avere la mia torta e mangiarla anch'io?

Grazie!

+0

E harkens la domanda ... perché 'typedef' a tutti? Per funzionalità ridotte e una linea di codice semi-ridondante? Forse questo è il modo di dire di Apple ... ___ "non farlo!" ___ ?? –

risposta

32

Puoi sicuramente avere la tua torta e mangiarla anche tu, se sei disposto ad aggiungere una riga di codice in più all'interfaccia di classe.

In primo luogo, definire blocco con un typedef e creare una proprietà come avete fatto nella vostra domanda:

typedef void (^CompletionBlock)(MyObject *myObj); 

... 

@property (nonatomic, copy) CompletionBlock completionBlock; 

Inoltre, come MobileOverload ha sottolineato nella sua risposta, sappiamo che Xcode fornisce il completamento del codice corretto per typedef' d blocchi se utilizzati in una dichiarazione di metodo standalone. Quindi, aggiungiamo una dichiarazione esplicita per il setter di completionBlock:

- (void)setCompletionBlock:(CompletionBlock)completionBlock; 

Quando ha chiamato, questo metodo consente di risolvere il metodo setter dichiarati dalla struttura. Tuttavia, poiché l'abbiamo definito esplicitamente nell'interfaccia di classe, Xcode lo vede e applica il completamento completo del codice.

Quindi, se si includono tutte e tre le linee, si dovrebbe ottenere il risultato desiderato. Questo comportamento è chiaramente una lacuna di Xcode, in quanto non vi è alcun motivo per cui un setter definito in un'istruzione @property debba avere un completamento di codice diverso rispetto allo stesso metodo definito a sé stante.

+2

Funziona, grazie!Presenterò una segnalazione di bug per questo, quindi spero che non ci servirà la dichiarazione esplicita del metodo in futuro. – Andrew

+0

Se aggiungo la dichiarazione di setter esplicita al mio file di interfaccia, ricevo un avviso di progetto che indica che ho un'implementazione incompleta. Se dichiaro questo setter nell'interfaccia, allora sono obbligato a implementarlo nel .m? – djibouti33

+0

Si dovrebbe ricevere questo avviso solo se non si sta dichiarando la proprietà o se il setter definito dalla proprietà ha una definizione diversa da quella dichiarata esplicitamente. – Matt

4

È possibile ottenere un completamento di codice dall'aspetto gradevole quando si passano i blocchi come argomento a un metodo della classe. Nel file di intestazione ho typedef il blocco come questo

typedef void (^MyCompletionBlock)(id obj1, id obj2); 

Poi sono stato in grado di usarlo come argomento per il mio metodo che ho anche dichiarato in questa intestazione di classe.

-(void)doThisWithBlock:(MyCompletionBlock)block; 

Nel file m ho dichiarato il metodo

-(void)doThisWithBlock:(MyCompletionBlock)block { 
    NSLog(@"Something"); 
} 

e quando sono andato a chiamarlo ho avuto il completamento del codice di fantasia come questo. CodeCompletion1

CodeCompletion2

Speriamo che questo risponde alla tua domanda.

+2

Sfortunatamente il comportamento è diverso e Xcode non usa la sintassi completa del blocco quando si definisce una '@ proprietà' con un tipo di blocco typedef e si usa un metodo setter definito manualmente o generato il setter' @ synthesize'. – Andrew

+2

Mi sono imbattuto nello stesso problema. A partire da Xcode 4.3.2 (4E2002) questo è corretto. Devi usare un typedef e una dichiarazione di metodo esplicita nella sezione dell'interfaccia. Quando si desidera ottenere il completamento completo del codice, non è possibile utilizzare né una proprietà né definire un metodo senza un blocco typedef. – Klaas

+0

È ANCORA simile a questo in Xcode (il numero dopo 4, redact me, se avete il coraggio). UGH! –

0

Non so sui completamenti di codice completo ma è possibile utilizzare frammenti di codice per ottenere il completamento del codice come comportamento ed è possibile utilizzare segnaposto in frammenti di codice < #PLACE HOLDER #>. Spero che questo ti possa aiutare

1

Ok così ho pensato un modo palliativo di fare questo che does't provocare avvertenze/errori ... e rende di fatto le cose più facili da leggere/più breve per tipo, ecc

definiscono una macro con il nostro "sigla", e quindi utilizzare il formato completo nella dichiarazione proprietà come ...

#define TINP NSString*(^)(NSString *typed, const char *raw) 
@interface .... 
@property (copy) NSString*(^termDidReadString)(NSString *typed, const char *raw); 

successivamente .. si può quindi fare riferimento che "tipo" di discussione, ecc come ..

+ (void)addInputBlock:(TINP)termDidReadString; 

e voilá ... non solo il tuo codice sarà TINIER !! ma il completamento del codice funziona, come un fascino ...

enter image description here