草庐IT

objective-c - Objective-C 属性的解释

coder 2024-01-10 原文

我正在读一本关于 iOS 的书(它叫做 Programming iOS 4,作者 Matt Neuburg),在他解释属性的段落中,他说了这些话:

Objective-C uses dot-notation for properties, and C uses dot-notation for structs; these can be chained. So, for example, UIView’s frame is a property whose value is a struct (a CGRect); thus, you can say myView.frame.size.height, where frame is a property that returns a struct, size is a component of that struct, and height is a component of that struct. But a struct is not a pointer, so you cannot (for example) set a frame’s height directly through a chain starting with the UIView, like this:

myView.frame.size.height = 36.0; // compile error

Instead, if you want to change a component of a struct property, you must fetch the property value into a struct variable, change the struct variable’s value, and set the entire property value from the struct variable:

CGRect f = myView.frame;
f.size.height = 0;
myView.frame = f;

我不太明白,为什么我不能使用下面的行?

myView.frame.size.height = 36.0;

最佳答案

背景

编程语言中的变量是一个盒子,它有一个名称(有时根据语言称为“引用”或“指针”)。这个盒子包含某种类型的值。值不会改变,盒子的内容会改变。例如在下面的代码中:

int a = 4;
a = 5;

第二行没有改变4,它改变了方框a中的内容。

编程语言中的类型分为两类:值类型引用类型

对于值类型,传递并存储在盒子中的是实际值的表示,例如在代码中:

double a = 9.0;
double b = sqrt(a);

函数 sqrt 不是传递给 a 而是传递给存储在 a 中的 value - 这是一些代表数字 9.0 的位序列; sqrt 返回的是一些表示 3.0 的位序列,这些位序列存储在 b 中。传递的位,您在您的评论之一中使用您的话,是“真正的值(value)”。

对于引用类型,传递并存储在盒子中的是包含实际值的盒子名称(内存块)的某种表示形式。在 Objective-C 中,引用类型通过在声明中使用 * 来区分(其他语言不需要 *,例如 Java 和 C# - 它们知道哪些类型是引用类型基于他们的种类)。例如在代码中:

NSWindow *main = [NSApp mainWindow];

方法调用不返回窗口值本身,而是返回包含窗口值的框的名称。再次使用您的话,“真正的值(value)”永远不会被传递,而是包含该值的盒子的名称被传递。

传统上,“小”类型由值类型表示——整数、 float 、字符等;而引用类型的“大”值。然而,每种编程语言都有自己的选择——有些甚至被定义为仅使用引用类型。

回答

在您的示例中,myView.frame 是一个属性,并且属性是使用方法实现的。在 Objective-C(和 C、C++)中,struct 类型是 value 类型 - 它被视为整数和 float ,它的值被传递和存储在盒子里。因此,用您的话来说,该属性返回的是“真实结构”——它与上例中表示 3.0 的位一样“真实”。

没有返回的是包含结构值的框的名称,如果不能访问框,则无法更改其内容。这就是为什么 myView.frame.size.height = 36.0; 不正确的原因 - 您正在尝试更改值的一部分,但值不会更改。

但是给定一个 NSRect 框,你可以改变它的部分内容。例如。在代码中:

NSRect aRect;
aRect.size.height = 36.0;

.size.height 标识框 aRect 的哪一部分要更改,36.0 的表示存储在该部分中的盒子。

HTH

关于objective-c - Objective-C 属性的解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9372433/

有关objective-c - Objective-C 属性的解释的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  5. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  6. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  7. ruby - Nokogiri 剥离所有属性 - 2

    我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog

  8. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

  9. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

  10. ruby - Chef Ruby 遍历 .erb 模板文件中的属性 - 2

    所以这可能有点令人困惑,但请耐心等待。简而言之,我想遍历具有特定键值的所有属性,然后如果值不为空,则将它们插入到模板中。这是我的代码:属性:#===DefaultfileConfigurations#default['elasticsearch']['default']['ES_USER']=''default['elasticsearch']['default']['ES_GROUP']=''default['elasticsearch']['default']['ES_HEAP_SIZE']=''default['elasticsearch']['default']['MAX_OP

随机推荐