使用 ivar 名称重构 iPhone

发布于 2024-10-04 12:01:45 字数 1133 浏览 4 评论 0原文

谁能告诉我如何在我的方法中动态指定 ivar 名称? l2 是我想要瞄准的 ivar。

//this works
if (maxunlocked > 1) { 

filename = [NSString stringWithFormat:@"level%d.png", [[fliesArray objectAtIndex:2] intValue]];
filenameHi = [NSString stringWithFormat:@"level%dHi.png", [[fliesArray objectAtIndex:2] intValue]];

l2 = [SoundMenuItem itemFromNormalSpriteFrameName:filename selectedSpriteFrameName:filenameHi target:self selector:@selector(level:)];

}

//这不是

    for (int i = 0; i<11; i++) {

    if (maxunlocked > i) {

    filename = [NSString stringWithFormat:@"level%d.png", [[fliesArray objectAtIndex:i] intValue]];
    filenameHi = [NSString stringWithFormat:@"level%dHi.png", [[fliesArray objectAtIndex:i] intValue]];


//this is where I'm attempting to dynamically specify the SoundMenuItem instance name.  
    sndMenuItem = [NSString stringWithFormat:@"l%d", i];

    sndMenuItem = [SoundMenuItem itemFromNormalSpriteFrameName:filename selectedSpriteFrameName:filenameHi target:self selector:@selector(level:)]; 
    sndMenuItem.userData = (id)i;
     }
    }

谢谢,

马克

Could anyone tell me how I can dynamically specify an ivar name within my method?
l2 is the ivar I'm trying to target.

//this works
if (maxunlocked > 1) { 

filename = [NSString stringWithFormat:@"level%d.png", [[fliesArray objectAtIndex:2] intValue]];
filenameHi = [NSString stringWithFormat:@"level%dHi.png", [[fliesArray objectAtIndex:2] intValue]];

l2 = [SoundMenuItem itemFromNormalSpriteFrameName:filename selectedSpriteFrameName:filenameHi target:self selector:@selector(level:)];

}

//this doesn't

    for (int i = 0; i<11; i++) {

    if (maxunlocked > i) {

    filename = [NSString stringWithFormat:@"level%d.png", [[fliesArray objectAtIndex:i] intValue]];
    filenameHi = [NSString stringWithFormat:@"level%dHi.png", [[fliesArray objectAtIndex:i] intValue]];


//this is where I'm attempting to dynamically specify the SoundMenuItem instance name.  
    sndMenuItem = [NSString stringWithFormat:@"l%d", i];

    sndMenuItem = [SoundMenuItem itemFromNormalSpriteFrameName:filename selectedSpriteFrameName:filenameHi target:self selector:@selector(level:)]; 
    sndMenuItem.userData = (id)i;
     }
    }

Thanks,

Mark

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

别理我 2024-10-11 12:01:49

如果您将其声明为属性,则可以使用 KVC 来获取它。

float h1 = [object height];
float h2 = [[object valueForKey:@"height"] floatValue];

[编辑]

我没听懂你在说什么。答案是否定的。您无法动态指定变量名称。你可以做的是:

// if `l2` is a member of self. (as in self.l2)
for (int i = 0; i<11; i++) {

    if (maxunlocked > i) {

    filename = [NSString stringWithFormat:@"level%d.png", [[fliesArray objectAtIndex:i] intValue]];
    filenameHi = [NSString stringWithFormat:@"level%dHi.png", [[fliesArray objectAtIndex:i] intValue]];


//this is where I'm attempting to dynamically specify the SoundMenuItem instance name.  
    key = [NSString stringWithFormat:@"l%d", i];

    tmp = [SoundMenuItem itemFromNormalSpriteFrameName:filename selectedSpriteFrameName:filenameHi target:self selector:@selector(level:)]; 
    tmp.userData = (id)i;

    [self setValue:tmp forKey:key];
     }
    }

[编辑]

你可能应该重新构建你的整个班级。

@interface myViewController: NSViewController {
    UIButton *sound1;
    UIButton *sound2;

    SoundMenuItem *l1;
    SoundMenuItem *l2;
}

@property (assign) IBOutlet UIButton *sound1; // connect up in IB
@property (assign) IBOutlet UIButton *sound2;

- (IBAction) clickSoundButton: (id)sender; // connect up to sound1 and sound2 in IB
- (SoundMenuItem) getSoundMenuItem: (int) i;

@end

@implementation myViewController

- (IBAction) clickSoundButton: (id)sender
{
   if (sender == (id)sound1) l1 = [self getSoundMenuItem: 1];
   if (sender == (id)sound2) l2 = [self getSoundMenuItem: 2];
}

- (SoundMenuItem) getSoundMenuItem: (int) i
{
if (maxunlocked <= i) return

    NSString *filename = [NSString stringWithFormat:@"level%d.png", [[fliesArray objectAtIndex:i] intValue]];
    NSString *filenameHi = [NSString stringWithFormat:@"level%dHi.png", [[fliesArray objectAtIndex:i] intValue]];

    SoundMenuItem *sndMenuItem = [SoundMenuItem itemFromNormalSpriteFrameName:filename selectedSpriteFrameName:filenameHi target:self selector:@selector(level:)]; 
    sndMenuItem.userData = (id)i;
    return sndMenuItem; //(assuming it is auto-released)
}
@end

If you have it declared as a property, you may be able to use KVC to get it.

float h1 = [object height];
float h2 = [[object valueForKey:@"height"] floatValue];

[EDIT]

I didn't understand what you're saying. The answer is no. You can't specify a variable name dynamically. What you can do is this:

// if `l2` is a member of self. (as in self.l2)
for (int i = 0; i<11; i++) {

    if (maxunlocked > i) {

    filename = [NSString stringWithFormat:@"level%d.png", [[fliesArray objectAtIndex:i] intValue]];
    filenameHi = [NSString stringWithFormat:@"level%dHi.png", [[fliesArray objectAtIndex:i] intValue]];


//this is where I'm attempting to dynamically specify the SoundMenuItem instance name.  
    key = [NSString stringWithFormat:@"l%d", i];

    tmp = [SoundMenuItem itemFromNormalSpriteFrameName:filename selectedSpriteFrameName:filenameHi target:self selector:@selector(level:)]; 
    tmp.userData = (id)i;

    [self setValue:tmp forKey:key];
     }
    }

[EDIT]

You should probably re-structure your entire class.

@interface myViewController: NSViewController {
    UIButton *sound1;
    UIButton *sound2;

    SoundMenuItem *l1;
    SoundMenuItem *l2;
}

@property (assign) IBOutlet UIButton *sound1; // connect up in IB
@property (assign) IBOutlet UIButton *sound2;

- (IBAction) clickSoundButton: (id)sender; // connect up to sound1 and sound2 in IB
- (SoundMenuItem) getSoundMenuItem: (int) i;

@end

@implementation myViewController

- (IBAction) clickSoundButton: (id)sender
{
   if (sender == (id)sound1) l1 = [self getSoundMenuItem: 1];
   if (sender == (id)sound2) l2 = [self getSoundMenuItem: 2];
}

- (SoundMenuItem) getSoundMenuItem: (int) i
{
if (maxunlocked <= i) return

    NSString *filename = [NSString stringWithFormat:@"level%d.png", [[fliesArray objectAtIndex:i] intValue]];
    NSString *filenameHi = [NSString stringWithFormat:@"level%dHi.png", [[fliesArray objectAtIndex:i] intValue]];

    SoundMenuItem *sndMenuItem = [SoundMenuItem itemFromNormalSpriteFrameName:filename selectedSpriteFrameName:filenameHi target:self selector:@selector(level:)]; 
    sndMenuItem.userData = (id)i;
    return sndMenuItem; //(assuming it is auto-released)
}
@end
叶落知秋 2024-10-11 12:01:49

抱歉缺少信息,感谢您的耐心等待。由于字符限制,我很难将其全部添加到评论区。

这就是我正在尝试的...

在我的头文件中:

//SoundMenuItem 是一个类
声音菜单项 *l1;
声音菜单项 *l2; (我实际上有 20 个按钮,每个游戏级别一个)

在我的 .m 文件中

//here I set up the l1 button which is never locked
l1 = [SoundMenuItem itemFromNormalSpriteFrameName:filename selectedSpriteFrameName:filenameHi target:self selector:@selector(level:)];

//and here I set the l2 button to be locked by default  
l2 = [SoundMenuItem itemFromNormalSpriteFrameName:@"levellock.png" selectedSpriteFrameName:@"levellockHi.png" target:self selector:@selector(doNothing:)];

//现在我检查 level2 是否已解锁(maxunlocked > 1),如果是,我重置 l2 实例以使用不同的图像。

if (maxunlocked > 1) {

filename = [NSString stringWithFormat:@"level%d.png", [[fliesArray objectAtIndex:2] intValue]];
filenameHi = [NSString stringWithFormat:@"level%dHi.png", [[fliesArray objectAtIndex:2] intValue]];

l2 = [SoundMenuItem itemFromNormalSpriteFrameName:文件名 selectedSpriteFrameName:文件名Hi 目标:self 选择器:@selector(level:)];

因此,

我不想对上述 if 语句进行 20 次迭代,而是每个按钮迭代一次,我想将其重构为一次。

我希望我已经说得更清楚了。

Sorry about the lack of info and thanks for your patience. I was struggling to add it all into the comments area due to the character limit.

This is what I'm attempting...

In my header file:

//SoundMenuItem is a class
SoundMenuItem *l1;
SoundMenuItem *l2; (I actually have 20 buttons, one for each game level)

In my .m file

//here I set up the l1 button which is never locked
l1 = [SoundMenuItem itemFromNormalSpriteFrameName:filename selectedSpriteFrameName:filenameHi target:self selector:@selector(level:)];

//and here I set the l2 button to be locked by default  
l2 = [SoundMenuItem itemFromNormalSpriteFrameName:@"levellock.png" selectedSpriteFrameName:@"levellockHi.png" target:self selector:@selector(doNothing:)];

//now I check to see if level2 has been unlocked (maxunlocked > 1) and if so I reset the l2 instance to use different images.

if (maxunlocked > 1) {

filename = [NSString stringWithFormat:@"level%d.png", [[fliesArray objectAtIndex:2] intValue]];
filenameHi = [NSString stringWithFormat:@"level%dHi.png", [[fliesArray objectAtIndex:2] intValue]];

l2 = [SoundMenuItem itemFromNormalSpriteFrameName:filename selectedSpriteFrameName:filenameHi target:self selector:@selector(level:)];

}

So rather than having 20 iterations of the above if statement, one for each button I'm wanting to refactor it into one.

I hope I've made myself clearer.

护你周全 2024-10-11 12:01:49

问题澄清后,我的第一个答案无效。 @stephen 的答案以及使用字典来保留所有 SoundMenuItem 的建议也是我所提议的。

After the question was clarified my first answer was not valid. The answer by @stephen with the suggestion for using a dictionary to keeping all the SoundMenuItem is what I would have proposed as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文