2009-05-22 15 views
9

mia comprensione è che i protocolli sono come interfacce in altre lingue - dichiarano i metodi previsti - (. Forse anche tipi non si è proprietari), mentre le categorie consentono di aggiungere nuovi metodi per esistenti tipiPerché l'SDK dell'iPhone utilizza categorie, piuttosto che protocolli, per alcuni delegati?

Perché, allora , l'SDK dell'iPhone a volte utilizza categorie per la dichiarazione dei tipi di delegati? Normalmente mi aspetterei che tutti i delegati vengano digitati id <MyDelegateProtocol> ma ci sono molti esempi in cui questo non è il caso.

Ad esempio, vedere NSURLConnection. Il suo delegato è digitato "id" e il "contratto" è dichiarato come categoria su NSObject (NSURLConnectionDelegate).

Quindi: qual è la motivazione per l'utilizzo di categorie in questi casi?

risposta

13

Objective-C 2.0 ha introdotto la direttiva del protocollo @optional, che consente di dichiarare facoltativi determinati metodi di protocollo. Prima di Obj-C 2.0, sono state utilizzate categorie per consentire metodi di delega facoltativi (in particolare, categorie su NSObject, che sono chiamati protocolli informali ).

La mia ipotesi è che la maggior parte dell'uso di categoria al posto del protocollo nell'SDK di iPhone è un residuo delle classi Mac equivalenti. Ad esempio, NSURLConnection esiste in entrambi gli SDK di Mac e iPhone, quindi è probabile che il codice sia condiviso. Dal momento che Apple non è ancora riuscita a modificare tutte le classi Mac per utilizzare i protocolli formali, ci rimane una certa incoerenza.

+0

Questa era la mia ipotesi, ma non lo sapevo per certo. Grazie! –

+0

Aspettatevi di vedere la modifica dei protocolli che arriva molto presto, però. Ora che sono consentiti metodi di protocollo opzionali, l'utilizzo di questi ripulirà un po 'il codice e libererà molte categorie ormai inutili. (Sono fantastici e tutto, ma invece di applicare metodi su NSObject in fase di esecuzione, penso che avere un delegato implementare un protocollo sia molto più pulito, sia concettualmente che dal punto di vista runtime.) –

4

Fino alla revisione dell'Obiettivo-C che era stato implementato con OS X 10.5 e l'SDK di iPhone, chiamato "Objective-C 2.0", si potevano solo fare protocolli opzionali usando le categorie. In Objective-C 2.0, una nuova parola chiave @optional è stata aggiunta nei protocolli per indicare quali metodi erano facoltativi (il resto è implicitamente richiesto).

Quindi penso che quello che vedi è un leggero ritardo rispetto ai giorni precedenti alla parola chiave @optional.

Modifica: Per rispondere al follow-up che è apparso nella domanda originale: La motivazione per l'utilizzo di una categoria su NSObject/id per un protocollo informale è in parte per documentare e raggruppare i metodi che l'oggetto può chiamare nella sua origine dati (o delegato o qualsiasi altra cosa), e in misura minore per evitare avvisi del compilatore che stai chiamando metodi che il compilatore non sa sarà presente nell'oggetto che riceve la chiamata. Immagina di essere quello che implementa la classe che chiama questi metodi di origine dati - probabilmente vorrai controllare che il metodo sia presente usando [obj respondsToSelector: @selector (my: datasource: method :)] ogni volta che sei interessato a chiamare il mio : datasource: method: metodo sull'oggetto obj.

+0

Ha senso - grazie! –

1

Questa è un'eredità derivata dall'obiettivo-c 1.0, che non ha "metodo di protocollo opzionale".

Problemi correlati