Ich möchte ein NSDictionary
haben, die auf etwas anderes aus UIView
s abbildet.UIView als Wörterbuchschlüssel?
Da jedoch UIViews nicht das NSCopying
Protokoll implementieren, kann ich sie nicht direkt als Dictionary-Schlüssel verwenden.
Ich möchte ein NSDictionary
haben, die auf etwas anderes aus UIView
s abbildet.UIView als Wörterbuchschlüssel?
Da jedoch UIViews nicht das NSCopying
Protokoll implementieren, kann ich sie nicht direkt als Dictionary-Schlüssel verwenden.
Sie können einen NSValue
verwenden, der den Zeiger auf UIView
hält und diesen als Schlüssel verwendet. NSValues
sind kopierbar. aber, wenn die Ansicht zerstört wird, halten die NSValue
einen Junk-Zeiger. Hier
Fabulous! Ich war dabei, eine NSNumber mit dem UIView-Hash als int zu verwenden. Das ist viel schöner, denke ich. –
Jetzt mit ARC müssen Sie 'valueWithNonretainedObject' verwenden. –
@Yar Hier ist der eigentliche Code mit Vorschlägen von luviere und dir: http://StackOverflow.com/a/11387017/974531 –
ist der eigentliche Code (basierend auf the answer by luvieere und weiterer Vorschlag von Yar):
// create dictionary
NSMutableDictionary* dict = [NSMutableDictionary new];
// set value
UIView* view = [UILabel new];
dict[[NSValue valueWithNonretainedObject:view]] = @"foo";
// get value
NSString* foo = dict[[NSValue valueWithNonretainedObject:view]];
Wie kann ich überprüfen, ob die Ansicht freigegeben wurde oder nicht? –
Obwohl dies nicht wirklich das, was sie für bestimmt sind, könnten Sie eine funktionelle Wörterbuch-ähnliche Oberfläche Peitsche Associative References mit:
static char associate_key;
void setValueForUIView(UIView * view, id val){
objc_setAssociatedObject(view, &associate_key, val, OBJC_ASSOCIATION_RETAIN);
}
id valueForUIView(UIView * view){
return objc_getAssociatedObject(view, &associate_key);
}
Man könnte sogar diese in einer Klasse einpacken ThingWhatActsLikeADictionaryButWithKeysThatArentCopyable
*; In diesem Fall sollten Sie die Ansichten beibehalten, die Sie als Schlüssel verwenden.
So etwas wie diese (nicht getestet):
#import "ThingWhatActsLikeADictionaryButWithKeysThatArentCopyable.h"
#import <objc/runtime.h>
static char associate_key;
@implementation ThingWhatActsLikeADictionaryButWithKeysThatArentCopyable
- (void)setObject: (id)obj forKey: (id)key
{
// Remove association and release key if obj is nil but something was
// previously set
if(!obj){
if([self objectForKey:key]){
objc_setAssociatedObject(key, &associate_key, nil, OBJC_ASSOCIATION_RETAIN);
[key release];
}
return;
}
[key retain];
// retain/release for obj is handled by associated objects functions
objc_setAssociatedObject(key, &associate_key, obj, OBJC_ASSOCIATION_RETAIN);
}
- (id)objectForKey: (id)key
{
return objc_getAssociatedObject(key, &associate_key);
}
@end
* Der Name etwas Arbeit benötigen.
Anstatt speichern einen Zeiger auf die Ansicht und riskieren, den Müll Problem, geben Sie einfach die UIView einen Tag und den Wert des Tags im Wörterbuch. Viel sicherer.
Ich verwende eine einfache Lösung unter ARC von Objective-C++ zur Verfügung gestellt.
MyClass.mm:
#import <map>
@implementation MyClass
{
std::map<UIView* __weak, UIColor* __strong> viewMap;
}
- (void) someMethod
{
viewMap[self.someView] = [UIColor redColor];
}
In diesem Beispiel habe ich, indem alle Werte stärker Typprüfung bin immer haben eine UIColor*
sein, die alles, was ich dies für erforderlich ist. Aber man könnte auch id
als Werttyp verwenden, wenn Sie ein beliebiges Objekt als Wert, ab zulassen möchten: std::map<UIView* __weak, id __strong> viewMap;
Ebenso für Schlüssel: id __weak, id __strong> viewMap;
Sie können auch variieren die __strong
und __weak
Attribute nach Bedarf. In meinem Fall werden die Ansichten vom View-Controller, in dem ich diesen benutze, bereits beibehalten, sodass ich keinen starken Zeiger darauf sehen musste.
NSMapTable bietet dies auch. c.f. '[ – nielsbot
Sofern Sie vor iOS 6 keine Unterstützung benötigen, funktioniert NSMapTable (empfohlen von neilsbot) gut, da es einen Enumerator über die Schlüssel in der Auflistung bereitstellen kann. Das ist nützlich für Code, der allen Textfeldern gemeinsam ist, wie das Festlegen des Delegaten oder das bidirektionale Synchronisieren der Textwerte mit einer NSUserDefaults-Instanz.
in viewDidLoad
self.userDefFromTextField = [NSMapTable weakToStrongObjectsMapTable];
[self.userDefFromTextField setObject:@"fooUserDefKey" forKey:self.textFieldFoo];
[self.userDefFromTextField setObject:@"barUserDefKey" forKey:self.textFieldBar];
// skipped for clarity: more text fields
NSEnumerator *textFieldEnumerator = [self.userDefFromTextField keyEnumerator];
UITextField *textField;
while (textField = [textFieldEnumerator nextObject]) {
textField.delegate = self;
}
in viewWillAppear:
NSEnumerator *keyEnumerator = [self.userDefFromTextField keyEnumerator];
UITextField *textField;
while (textField = [keyEnumerator nextObject]) {
textField.text = [self.userDefaults stringForKey:[self.textFields objectForKey:textField]];
}
in textfield: shouldChangeCharactersInRange: replacementString:
NSString *resultingText = [textField.text stringByReplacingCharactersInRange:range withString:string];
if(resultingText.length == 0) return YES;
NSString *preferenceKey = [self.textFields objectForKey:textField];
if(preferenceKey) [self.userDefaults setString:resultingText forKey:preferenceKey];
return YES;
Und jetzt werde ich weinen, weil ich all dies umgesetzt bevor ich feststelle, dass meine iOS 5.1-zielgerichtete App es nicht nutzen kann. NSMapTable in iOS eingeführt wurde 6.
Dies ist eine großartige Lösung! –
eine einfache Lösung, wenn Sie nur wollen, UIView
als Schlüssel gelegentlich, ich benutze es UILabel
und UIColor
NSArray<UIView *> *views = @[viewA,viewB,viewC,viewD];
NSArray *values = @[valueA,valueB,valueC,valueD];
for(int i = 0;i < 4;i++) {
UIView *key = views[i];
id value = values[i]
//do something
}
id value = values[[views indexOfObject:key]]
Relevant zu speichern: http://stackoverflow.com/questions/1497622/nsmanagedobject-as-nsdictionary-key – kennytm
Das klingt nach einer wirklich sehr schlechten Idee. –
Nur, wenn Sie nicht wissen, dass die Daten zu Müll werden könnten (wie die akzeptierte Antwort darauf hinweist). – mrueg