我在理解这段代码时遇到了一些麻烦。这是我正在阅读的一本书,但我觉得这个人只是告诉我在没有深入解释的情况下输入内容。
- (IBAction)sliderChanged:(id)sender
{
UISlider *slider = (UISlider *)sender; //set slidervar as active slider
int progressAsInt = (int)(slider.value + 0.5f);
NSString newText = [[NSString alloc] initWithFormat:@"%d",progressAsInt];
sliderLabel.text = newText;
[newText release];
}
问题在于第一行
UISlider *slider = (UISlider *)sender; //set slidervar as active slider
我不明白什么是类型转换,这就是那个人在书中所说的。 “避免每次使用时都需要对发送者进行类型转换”
我也不明白第二行在括号中有int
的原因/原因。我习惯拥有像
int progressAsInt = 56
答案 0 :(得分:2)
你的问题是你不理解C. Objective-C是C上的一个薄层,它添加了类和消息。检查好的C书,例如来自"The Definitive C Book Guide and List"的书。
如果没有获得对作为UISlider *
输入的对象的引用,则在每个实例中,如果没有将sender
引用转换为所需类型,则无法使用属性语法,例如,((UISlider *)sender).value
。即使您没有使用属性点表示法,也需要使用强制转换来让编译器将[slider value]
视为返回除id
以外的任何内容。
id
。当您知道发件人总是属于某种类型时 - 就像在这种情况下,代码假定sender
总是一种UISlider
- 您可以使用它输入方法声明:
- (IBAction)sliderChanged:(UISlider *)sender
{
/* code */
}
这更好地记录了程序员的意图 - Interface Builder所接受的文档 - 以及完全不需要在方法中进行任何转换。
一般来说,如果你需要进行类型转换,你很可能会做错事。
作为另一个例子,让我们来看看这一行:
int progressAsInt = (int)(slider.value + 0.5f);
这里,显式int
类型转换是不必要的。由于赋值是int
左值,因此添加产生的浮点值必须作为赋值的一部分强制转换为int
。
答案 1 :(得分:2)
类型转换是一种告诉编译器某些东西与它不同的类型的方法。它涉及你问题的两个部分。你通过在你正在施放的物品之前将新类型放在括号中来施放东西。
UISlider *slider = (UISlider *)sender;
声明方法后,sender
的类型为id
。因为您知道它应该是一个滑块,所以将它转换为UISlider *
并将其存储在具有该类型的变量中,以便编译器在您尝试使用特定于滑块的属性时不会给出警告。
int progressAsInt = (int)(slider.value + 0.5f);
这里,slider.value
是一个浮点数。由于您希望将其存储为整数类型,因此需要进行强制转换。当float转换为int时,它会自动舍入为零。代码希望它舍入到最接近的整数,因此在转换之前它会增加0.5。
答案 2 :(得分:1)
基本上,计算机(编译器,实际上,但我们可以假装为了简单起见)只知道你所指的是什么类型的东西,因为它的“类型”。类型可以是int, or
UISlider *,或任何其他数量的东西。它是变量的分类。
在顶部,您可以看到sender
的类型为id
,这意味着计算机不知道它是什么类型的对象。
调用此方法时,会收到一个名为sender
的对象。但即使您知道发件人是UISlider*
,也无法在其上调用UISlider方法,因为计算机不知道。
当你说UISlider *slider = (UISlider *)sender;
时,你说“嘿,电脑,我告诉你发件人是UISlider *
,我将把它称为slider
来自现在开始了。这就是类型转换。
int progressAsInt = (int)(slider.value + 0.5f);
(slider.value + 0.5f)
实际上是float
,类似于带小数的数字。你不能只为一个int
s的变量赋一个浮点数,所以你可以把(int)
放在前面,然后你说“请把这个浮点数换成一个int”。