gpt4 book ai didi

iphone - Objective-C 中的 Javascript 样式对象

转载 作者:搜寻专家 更新时间:2023-10-30 19:45:21 25 4
gpt4 key购买 nike

背景:我在我的 iPhone 和 iPad 代码中使用了大量的 NSDictionary 对象。我厌倦了获取/设置这些状态字典键的冗长方式。

那么一点点实验:我刚刚创建了一个我称之为 Remap 的类。

Remap 将采用任意的 set[VariableName]:(NSObject *) obj 选择器并将该消息转发给一个函数,该函数会将 obj 插入到键 [vairableName] 下的内部 NSMutableDictionary 中。

Remap 还将采用任意(零参数)任意 [variableName] 选择器并返回映射到键 [variableName] 下的 NSMutableDictionary 中的 NSObject。

例如

Remap * remap = [[Remap alloc] init];

NSNumber * testNumber = [NSNumber numberWithInt:46];
[remap setTestNumber:testNumber];
testNumber = [remap testNumber];

[remap setTestString:@"test string"];
NSString * testString = [remap testString];

NSMutableDictionary * testDict = [NSMutableDictionary dictionaryWithObject:testNumber forKey:@"testNumber"];
[remap setTestDict:testDict];
testDict = [remap testDict];

其中没有属性 testNumber、testString 或 testDict 在 Remap 中实际定义。

疯狂的事情?它有效...我唯一的问题是如何禁用“可能无法响应”仅访问 Remap 的警告

附言:我可能最终会放弃这个并使用宏,因为消息转发效率很低......但除此之外,还有人看到 Remap 的其他问题吗?

对于那些好奇的人,这是 Remap 的 .m:

#import "Remap.h"

@interface Remap ()
@property (nonatomic, retain) NSMutableDictionary * _data;
@end

@implementation Remap

@synthesize _data;

- (void) dealloc
{
relnil(_data);
[super dealloc];
}

- (id) init
{
self = [super init];
if (self != nil) {
NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];
[self set_data:dict];
relnil(dict);
}
return self;
}


- (void)forwardInvocation:(NSInvocation *)anInvocation
{
NSString * selectorName = [NSString stringWithUTF8String: sel_getName([anInvocation selector])];

NSRange range = [selectorName rangeOfString:@"set"];

NSInteger numArguments = [[anInvocation methodSignature] numberOfArguments];

if (range.location == 0 && numArguments == 4)
{
//setter
[anInvocation setSelector:@selector(setData:withKey:)];
[anInvocation setArgument:&selectorName atIndex:3];
[anInvocation invokeWithTarget:self];
}
else if (numArguments == 3)
{
[anInvocation setSelector:@selector(getDataWithKey:)];
[anInvocation setArgument:&selectorName atIndex:2];
[anInvocation invokeWithTarget:self];
}


}

- (NSMethodSignature *) methodSignatureForSelector:(SEL) aSelector
{
NSString * selectorName = [NSString stringWithUTF8String: sel_getName(aSelector)];

NSMethodSignature * sig = [super methodSignatureForSelector:aSelector];

if (sig == nil)
{
NSRange range = [selectorName rangeOfString:@"set"];

if (range.location == 0)
{
sig = [self methodSignatureForSelector:@selector(setData:withKey:)];
}
else
{
sig = [self methodSignatureForSelector:@selector(getDataWithKey:)];
}
}

return sig;
}

- (NSObject *) getDataWithKey: (NSString *) key
{
NSObject * returnValue = [[self _data] objectForKey:key];
return returnValue;
}


- (void) setData: (NSObject *) data withKey:(NSString *)key
{
if (key && [key length] >= 5 && data)
{
NSRange range;
range.length = 1;
range.location = 3;

NSString * firstChar = [key substringWithRange:range];
firstChar = [firstChar lowercaseString];

range.length = [key length] - 5; // the 4 we have processed plus the training :
range.location = 4;

NSString * adjustedKey = [NSString stringWithFormat:@"%@%@", firstChar, [key substringWithRange:range]];

[[self _data] setObject:data forKey:adjustedKey];
}
else
{
//assert?
}
}

@end

最佳答案

很酷的类(class)。我喜欢它。

我想不出一种方法来抑制您的所有警告,但我们可以将其减少到每个属性一行。将此添加到您的 Remap.h:

#define RemapProperty(PROP) \
@interface Remap(PROP) \
@property (nonatomic, retain) id PROP; \
@end \
@implementation Remap(PROP) \
@dynamic PROP; \
@end

现在您可以通过将其放在给您警告的文件顶部来抑制给定属性的所有重映射警告:

RemapProperty(propertyName);

这需要一些额外的工作,但它会给你点语法作为奖励。

remap.propertyName = @"Foo";

再做一些工作,您就可以定义一个类似的宏,将属性直接添加到 NSDictionary,从而不需要 Remap 类。

关于iphone - Objective-C 中的 Javascript 样式对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2908721/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com