加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

objective-c – Objective C – Accessors,即Getters / Setters

发布时间:2020-12-16 03:16:39 所属栏目:百科 来源:网络整理
导读:我已经广泛阅读了已经发布的问题,并且找不到我正在寻找的答案. 我完全理解使用@syntesize指令创建getter和setter方法的概念(即如果我有@property int width和@synthesize width,我无意中创建了一个宽度的getter方法和setWidth的setter方法:). 但是,当我没有
我已经广泛阅读了已经发布的问题,并且找不到我正在寻找的答案.

我完全理解使用@syntesize指令创建getter和setter方法的概念(即如果我有@property int width和@synthesize width,我无意中创建了一个宽度的getter方法和setWidth的setter方法:).

但是,当我没有使用@synthesize指令但是在@implementation部分中声明实例变量是对象时,我并不完全理解访问器方法的工作原理.这是我对以下代码不了解的内容:

1)在主要地方它说:

NSLog(@"Origin at (%i,%i)",myRect.origin1.x,myRect.origin1.y);

在我看来好像它会调用[[myRect origin1] x]方法,它首先确定[myRect origin1]返回原点然后立即调用[origin x]作为结果(然后对y执行相同操作) ).现在,让我失望的是,如果我要更改getter方法的名称

-(XYpoint *) origin1;

包含在Rectangle.h中

-(XYpoint *) origin2;

程序得到大量错误并停止编译.注意:我还在所引用的任何地方更改了此方法的名称,包括将main中的前面的代码更改为

NSLog(@"Origin at (%i,myRect.origin2.x,myRect.origin2.y);

但是,如果我还更改了setter方法的名称:

-(void) setOrigin1: (XYpoint *) pt

至:

-(void) setOrigin2: (XYpoint *) pt

然后一切都像以前一样有效.在我看来,只有当我的getter和setter都在x setX命名约定中命名时它才能正常工作.我认为这主要是我需要解释的:

A)如果我创建一个碰巧是对象的实例变量(在这种情况下就像’origin’),我必须为它创建getter和setter方法吗?

B)我可以创建一个getter方法但不能创建setter方法,反之亦然

C)如果我确实为’origin’创建了getter和setter方法,那么它们都必须以x setX方式命名.在这种情况下,作为 – (XYpoint *)origin1和 – (void)setOrigin1:(XYpoint *)pt.如果我更改了getter的名称,我必须相应地更改setter的名称?

这是所有代码:

Rectangle.h:

#import <Foundation/Foundation.h>
@class XYpoint;

@interface Rectangle : NSObject

@property int width,height;

-(XYpoint *) origin1;
-(void) setOrigin1: (XYpoint *) pt;
-(void) setWidth: (int) w andHeight: (int) h;
-(int) area;
-(int) perimeter;

@end

Rectangle.m:

#import "Rectangle.h"

@implementation Rectangle
{
    XYpoint *origin;
}

@synthesize  width,height;

-(void) setWidth:(int) w andHeight:(int)h
{
    width = w;
    height = h;
}


-(void) setOrigin1: (XYpoint *) pt
{
    origin = pt;
}

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

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

-(XYpoint *) origin1
{
    return origin;
}

@end

XYpoint.h:

#import <Foundation/Foundation.h>

@interface XYpoint : NSObject

@property int x,y;

-(void) setX: (int) xVal andY: (int) yVal;
@end

XYpoint.m:

#import "XYpoint.h"

@implementation XYpoint

@synthesize x,y;

-(void) setX: (int) xVal andY: (int) yVal
{
    x = xVal;
    y = yVal;
}
@end

main.m文件:

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

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

    @autoreleasepool {
        Rectangle *myRect = [[Rectangle alloc] init];
        XYpoint *myPoint = [[XYpoint alloc] init];

        [myPoint setX: 100 andY: 200];
        [myRect setWidth: 5 andHeight:8];
        myRect.origin1 = myPoint;
        NSLog(@"Rectangle w = %i,h = %i",myRect.width,myRect.height);
        NSLog(@"Origin at (%i,myRect.origin1.y);
        NSLog(@"Area = %i,Perimeter = %i",[myRect area],[myRect perimeter]);
    }
    return 0;
}

解决方法

通过电子邮件讨论后,我们发现问题实际上似乎是clang中的一个错误.考虑以下迷你程序:
#import <Foundation/Foundation.h>

@interface TestObject : NSObject
-(void)setIdVar:(id)someId;
@end

@implementation TestObject
-(void)setIdVar:(id)someId;
{
    NSLog(@"-setIdVar called with argument: %@",someId);
}
@end

int main (int argc,const char * argv[])
{
    @autoreleasepool {
        TestObject *testObj = [[TestObject alloc] init];
        testObj.idVar = @"test";
    }
    return 0;
}

显然,我们希望这个程序运行并使用参数:test调用输出-setIdVar.而这恰恰是在没有ARC的情况下编译它时会发生的事情(例如,使用clang -framework Foundation main.m).

但是如果我们用ARC编译它,clang会崩溃. (clang -framework Foundation -fobjc-arc main.m)

有趣的是,当使用setter作为非对象类型(例如int)或定义了getter时,不会发生这种崩溃.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读