objective-c – Objective C – Accessors,即Getters / Setters
我已经广泛阅读了已经发布的问题,并且找不到我正在寻找的答案.
我完全理解使用@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时,不会发生这种崩溃. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |