27

NSDictionarys から別のものにマップする a が必要UIViewです。

ただし、UIView はNSCopyingプロトコルを実装していないため、直接辞書のキーとして使用することはできません。

4

7 に答える 7

30

NSValueへのポインターを保持し、UIViewこれをキーとして使用できます。NSValues コピー可能です。ただし、ビューが破棄されるNSValueと、ジャンク ポインターが保持されます。

于 2010-06-07T19:09:20.710 に答える
17

実際のコードは次のとおりです(luvieereによる回答と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]];
于 2012-07-08T21:53:32.193 に答える
4

これは実際には意図したものではありませんが、連想参照を使用して機能的な辞書のようなインターフェイスを作成できます。

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);
}

これをクラスThingWhatActsLikeADictionaryButWithKeysThatArentCopyable*;にまとめることもできます。その場合、キーとして使用するビューを保持したい場合があります。

このようなもの(テストされていません):

#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

※名前は加工が必要な場合があります。

于 2012-07-08T22:04:13.327 に答える
4

iOS 6 より前にサポートする必要がない場合、NSMapTable ( neilsbotが推奨) は、コレクション内のキーに対して列挙子を提供できるため、うまく機能します。これは、デリゲートの設定やテキスト値と NSUserDefaults インスタンスとの双方向同期など、すべてのテキスト フィールドに共通するコードに便利です。

ビューでDidLoad

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;
}

ビューに表示されます:

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;

iOS 5.1 をターゲットにしたアプリが使えないことに気付く前に、これらすべてを実装したので、今は泣きそうです。 NSMapTable は iOS 6 で導入されました。

于 2014-12-09T22:06:50.380 に答える
1

ビューへのポインターを保存してガベージの問題を回避するのではなく、UIView にタグを付けて、タグの値をディクショナリに保存します。はるかに安全です。

于 2012-10-18T23:48:50.350 に答える
0

時々鍵として使いたいときの簡単な解決策ですUIView。私はそれを使用して保管UILabelし、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]]
于 2017-07-21T08:45:31.293 に答える