3

对不起,我不能在标题中更具描述性。我知道 C++ 和 C#,以及一点 Java,我正在做一些 Objective C 教程,但无法解释这里发生了什么。

我将向您展示一个示例:

这是矩形类的标题/接口:

#import <Foundation/Foundation.h>

@class XYPoint;
@interface Rectangle : NSObject

@property int width, height;

-(int) area;
-(int) perimeter;
-(void) setW:(int)w andH:(int)h;
-(XYPoint *) origin;
-(void) setOrigin:(XYPoint*)pt;

@end

这是实现:

#import "Rectangle.h"

@implementation Rectangle{
    XYPoint *origin;
}

@synthesize width, height;

-(void) setW:(int)w andH:(int)h
{
    width = w;
    height = h;
}

-(int) area{
    return width*height;
}

-(int) perimeter{
    return (width+height)*2;
}

-(XYPoint *) origin{
    return origin;
}
-(void) setOrigin:(XYPoint*)pt{
    origin = pt;
}

@end

这是我的主要程序:

#import <Foundation/Foundation.h>
#import "Rectangle.h"
#import "XYPoint.h"


int main(int argc, const char * argv[])
{
    @autoreleasepool {

        Rectangle *r = [[Rectangle alloc]init];
        XYPoint *p = [[XYPoint alloc]init];

        [p setX:100 andY:300];
        [r setW:6 andH:8];

        r.origin = p;

        NSLog(@"Width and height is %i %i", r.width, r.height);
        NSLog(@"Origin is at %i,%i", r.origin.x, r.origin.y);
        NSLog(@"Arear and perimeter are %i and %i", [r area], [r perimeter]);

    }
    return 0;
}

这条线r.origin = p;让我很困惑。这里具体指的是哪个来源?接口中定义的getter方法,还是实现中声明的实际成员变量?

注意来源不是属性。

老实说,我预计会出现错误。主程序应该只看到 getter 方法,但它似乎不像返回某些东西的 getter 方法可能位于赋值运算符的左侧。或者系统是否以某种方式将该语法映射到对 setOrigin 的调用?

我曾期望设置原点的唯一可能方法是[r setOrigin: p]

我可以看到类似的东西是如何r.width = 5工作的,就像在标题中声明的宽度一样,它是一个属性,但我看不到它是如何r.origin = p工作的。

有人可以解释这里发生了什么吗?

谢谢。

4

2 回答 2

3

您的猜测是正确的 - 称为点表示法的语法被[r setOrigin:p]编译器转换为调用。一般的想法是,就像大多数其他语言一样,您有对象属性的 getter 和 setter。在 Objective-C 中,这些通常写成:

- (type)variableName;
- (void)setVariableName:(type)aVariable;

只要您自己的代码符合这些约定,您就可以使用点表示法来获取和设置类上的变量,并相信您的方法被调用。

幕后显然还有很多事情要做,所以我希望这个简短的解释对你来说已经足够了。但是,如果您有兴趣,可以进一步研究:

  • 综合属性和实际发生的情况 - 编译器生成上述形式的方法,以及用于实际数据存储的实例变量
  • 键值编码,它利用了这些原则和约定
  • 某些类型的特殊情况(例如,BOOL变量的 getter 通常写成-isVariableName而不是-variableName),以及如何使用@property属性来管理它们
于 2012-07-27T20:18:50.057 回答
1

是的,由点表示法调用的属性访问器会自动转换为编译器的方法调用;因此

variable = object.property;

相当于

variable = [object property];

object.property = variable;

相当于

[object setProperty:variable];
于 2012-07-27T20:27:05.177 回答