Objective c 我可以通过它修改变量吗';谁的名字是字符串?
有没有办法从包含变量名称的字符串中修改变量 大概是这样的:Objective c 我可以通过它修改变量吗';谁的名字是字符串?,objective-c,Objective C,有没有办法从包含变量名称的字符串中修改变量 大概是这样的: int example = 1; NSString *foo = @"example"; foo.value++ 在这一点上,example等于2。像这样的局部变量不能这样做。您可以使用实例变量来实现这一点。我不知道任何语言可以让您实现这一点 在这种特殊情况下,您可以传递一个指向int的指针 更一般地说,如果您想通过名称操纵某事物,请使用字典: NSDictionary* d = @{@"example":@1}; NSString*
int example = 1;
NSString *foo = @"example";
foo.value++
在这一点上,
example
等于2。像这样的局部变量不能这样做。您可以使用实例变量来实现这一点。我不知道任何语言可以让您实现这一点
在这种特殊情况下,您可以传递一个指向int
的指针
更一般地说,如果您想通过名称操纵某事物,请使用字典:
NSDictionary* d = @{@"example":@1};
NSString* key = @"example";
d[key] = @([d[key] intValue] + 1);
与其他答案相反,如果你愿意进入完整的黑客模式,这确实是可能的。利用C中宏和指针的强大功能,我完成了这项任务(它还包括关于对象类型的信息,以防您需要知道在运行时要做什么) 这是一个有趣的例子,但要小心——它会大大增加内存使用量 首先,让我们展示如何使用这些API:
main.m:
#import <Foundation/Foundation.h>
#import "IndexedVariable.h"
int main() {
INDEXED_VAR(int, example, 1);
NSString *foo = @"example";
GET_INDEXED_VAR_AS(foo, int)++;
NSLog(@"%i", example);
}
#import <Foundation/Foundation.h>
// feel free to not use these macros, but I feel they make it much easier to read
#define choose_if __builtin_choose_expr
#define compatible __builtin_types_compatible_p
#define INDEXED_TYPE_FROM_NAME(p_type) \
choose_if(compatible(signed char , p_type), INDEXED_TYPE_SIGNED_CHAR,\
choose_if(compatible(unsigned char , p_type), INDEXED_TYPE_UNSIGNED_CHAR,\
choose_if(compatible(signed short , p_type), INDEXED_TYPE_SIGNED_SHORT,\
choose_if(compatible(unsigned short, p_type), INDEXED_TYPE_UNSIGNED_SHORT,\
choose_if(compatible(signed int , p_type), INDEXED_TYPE_SIGNED_INT,\
choose_if(compatible(unsigned int , p_type), INDEXED_TYPE_UNSIGNED_INT,\
choose_if(compatible(signed long , p_type), INDEXED_TYPE_SIGNED_LONG,\
choose_if(compatible(unsigned long , p_type), INDEXED_TYPE_UNSIGNED_LONG,\
choose_if(compatible(float , p_type), INDEXED_TYPE_FLOAT,\
choose_if(compatible(double , p_type), INDEXED_TYPE_DOUBLE,\
choose_if(compatible(id , p_type), INDEXED_TYPE_OBJC_OBJECT,\
choose_if(compatible(void * , p_type), INDEXED_TYPE_GENERIC_POINTER,\
INDEXED_TYPE_UNKNOWN\
))))))))))))
#define INDEXED_VAR(p_type, p_name, p_initial_value)\
p_type p_name = p_initial_value;\
IndexedVariable *__indexed_ ## p_name = [IndexedVariable index:INDEXED_TYPE_FROM_NAME(p_type) :@#p_name :&p_name];\
(void) __indexed_ ## p_name
#define GET_INDEXED_VAR_AS(p_name, type) (*((type *) [[IndexedVariable lookupWithName:p_name] address]))
// represents the type of an indexed variable
enum INDEXED_TYPE {
INDEXED_TYPE_SIGNED_CHAR,
INDEXED_TYPE_UNSIGNED_CHAR,
INDEXED_TYPE_SIGNED_SHORT,
INDEXED_TYPE_UNSIGNED_SHORT,
INDEXED_TYPE_SIGNED_INT,
INDEXED_TYPE_UNSIGNED_INT,
INDEXED_TYPE_SIGNED_LONG,
INDEXED_TYPE_UNSIGNED_LONG,
INDEXED_TYPE_FLOAT,
INDEXED_TYPE_DOUBLE,
INDEXED_TYPE_OBJC_OBJECT,
INDEXED_TYPE_GENERIC_POINTER,
INDEXED_TYPE_UNKNOWN,
};
@interface IndexedVariable : NSObject
+(id) index:(enum INDEXED_TYPE) indexedType :(NSString *) varName :(void *) ptr;
+(IndexedVariable *) lookupWithName:(NSString *) name;
-(enum INDEXED_TYPE) indexedType;
-(void *) address;
@end
#import "IndexedVariable.h"
static NSMutableDictionary *indexedVariableDictionary;
@implementation IndexedVariable {
enum INDEXED_TYPE _type;
void *_address;
}
+(id) index:(enum INDEXED_TYPE)indexedType :(NSString *)varName :(void *)ptr
{
IndexedVariable *var = [IndexedVariable new];
var->_type = indexedType;
var->_address = ptr;
if (indexedVariableDictionary == nil) {
indexedVariableDictionary = [NSMutableDictionary new];
}
indexedVariableDictionary[varName] = [NSValue valueWithNonretainedObject:var];
return var;
}
+(IndexedVariable *) lookupWithName:(NSString *)name
{
return [indexedVariableDictionary[name] nonretainedObjectValue];
}
-(enum INDEXED_TYPE) indexedType {
return _type;
}
-(void *) address {
return _address;
}
-(void) dealloc {
NSArray *keys = [indexedVariableDictionary allKeysForObject:[NSValue valueWithNonretainedObject:self]];
[indexedVariableDictionary removeObjectsForKeys:keys];
}
@end
在本例中,您只能查找索引变量,其他任何内容都不在查找表中。该重复项不适用于局部变量。只有当
example
是一个属性时,它才会起作用。然而,我理解你的意思;怎么样还有,如果你真的愿意,你可以用本地人来做,但OFC会假设这涉及到服务器运行时和宏黑客。没有什么是不可能的,只是不切实际的。Python提供了这种绳索,如果你想要的话(就像其他解释语言可能做的那样):>a=10>>locals()['a']=12>>a
12
和javascript一样,你可以使用eval
,以及其他几种更复杂的方法。哦,是的,eval
-忘了那种事!早在20世纪80年代,很多种类的BASIC就已经实现了这一点。令人惊讶的是,这可以简化为使用苹果提供的AutoLayout()宏制作的字典中的查找@很遗憾,CodaFi不能像我的一样处理值类型。