Sto usando una categoria NSAttributedString (Additions) e ho davvero bisogno di un modo per aggiungere una proprietà che sarà una BOOL se la stringa è tag HTML o meno. So che le categorie non dovrebbero avere proprietà ma questo è il modo in cui ho bisogno di farlo. Sono stanco di scrivere i miei getter e setter ma non ha funzionato. Qualcuno sa come funziona?Come aggiungere la proprietà BOOL a una categoria?
risposta
Le categorie possono avere proprietà di sola lettura, non è possibile aggiungere semplicemente variabili di istanza con esse (beh, è possibile, una sorta di - vedere riferimenti associativi).
È possibile aggiungere un metodo di categoria (presentato da una proprietà di sola lettura) isHTMLTag
che restituirebbe un BOOL, si dovrebbe solo calcolare se si trattasse di un tag HTML ogni volta all'interno di tale metodo.
Se ti stai chiedendo di un modo per impostare il valore BOOL allora avrete bisogno di usare i riferimenti associati (objc_setAssociatedObject
) che non ho mai usato in modo non si sentono qualificati per rispondere a qualsiasi più in dettaglio.
Utilizzo dei riferimenti associati funzionanti! Grazie – Mace
Ti dispiacerebbe condividere come hai fatto a farlo funzionare? –
@Mace - puoi accettare la risposta di jrturton e aggiungere i dettagli da Joshua o accettare la risposta di Joshua ...? –
Se è davvero necessario aggiungere una proprietà, è necessario creare una sottoclasse anziché aggiungere una categoria.
A volte questo non è possibile. Ad esempio, se il codice che crea l'istanza di detta classe non è accessibile (ad esempio in una libreria statica). –
Per ragioni di completezza, questo è come ho ottenuto questo lavoro:
@interface
@interface ClassName (CategoryName)
@property (readwrite) BOOL boolProperty;
@end
@implementation
#import <objc/runtime.h>
static char const * const ObjectTagKey = "ObjectTag";
@implementation ClassName (CategoryName)
- (void) setBoolProperty:(BOOL) property
{
NSNumber *number = [NSNumber numberWithBool: property];
objc_setAssociatedObject(self, ObjectTagKey, number , OBJC_ASSOCIATION_RETAIN);
}
- (BOOL) boolProperty
{
NSNumber *number = objc_getAssociatedObject(self, ObjectTagKey);
return [number boolValue];
}
@end
E la gestione della memoria? L'istanza NSNumber viene mantenuta da solo all'interno del metodo -setBoolProperty :. Devo rilasciarlo in qualche modo? Da runtime.h: "@param value Il valore da associare alla chiave per l'oggetto Passa nil per cancellare un'associazione esistente." Ma non posso ignorare dealloc in una categoria. – igrek
Trovato una risposta qui: http://stackoverflow.com/questions/10842829/will-an-associated-object-be-released-automatically/10843510#10843510 Viene rilasciato correttamente – igrek
A proposito, è possibile omettere l'utilizzo di costanti aggiuntive per chiavi; invece, usa @selector (boolProperty) invece di ObjectTagKey, che fornirà esattamente ciò di cui hai bisogno – igrek
La mia soluzione, senza la necessità di una chiave oggetto e un po 'più facile da leggere la sintassi
NSString + Guida er.h
#import <Foundation/Foundation.h>
@interface NSString (Helper)
@property (nonatomic, assign) BOOL isHTML;
@end
NSString + helper.h
#import "NSString+Helper.h"
#import "objc/runtime.h"
@implementation NSString (Helper)
- (void)setIsHTML:(BOOL)isHTML
{
NSNumber *isHTMLBool = [NSNumber numberWithBool:isHTML];
objc_setAssociatedObject(self, @selector(isHTML), isHTMLBool, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)isHTML
{
NSNumber *isHTMLBool = objc_getAssociatedObject(self, @selector(isHTML));
return isHTMLBool.boolValue;
}
@end
Probabilmente molto tardi in questo mondo, quando Swift è già spazzando obiettivo c. In ogni caso, con Xcode 8, puoi anche usare le proprietà della classe, invece di usare riferimenti associativi.
@interface ClassName (CategoryName)
@property (class) id myProperty;
@end
@implementation
static id *__myProperty = nil;
+ (id)myProperty {
return __myProperty;
}
+ (void)setMyProperty:(id)myProperty {
__myProperty = myProperty;
}
@end
Dalle Xcode 8 note di rilascio:
Objective-C supporta ora proprietà della classe, che interagiscono con proprietà del tipo di Swift. Sono dichiarati come: @property (class) NSString * someStringProperty ;. Non sono mai sintetizzati. (23891898)
Swift 3:
Utilizzando questo metodo, è possibile aggiungere qualsiasi nuova proprietà (in questo caso aggiungere valore Bool) alla classe emozionante.
import ObjectiveC
private var xoAssociationKey: UInt8 = 0
extension <ClassName> {
var <propertyName>: Bool! {
get {
if let returnVal = objc_getAssociatedObject(self, &xoAssociationKey) as? Bool{
return returnVal
}else{
return false
}
}
set(newValue) {
objc_setAssociatedObject(self, &xoAssociationKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
}
}
possibile duplicato di [Objective-C: Property in Category] (http: // stackoverflow.it/questions/8733104/objective-c-property-in-category) –
Pubblica il codice per i tuoi getter e setter! – paulmelnikow