Objective-C геттер / сеттер - PullRequest
       12

Objective-C геттер / сеттер

10 голосов
/ 11 апреля 2010

Я пытаюсь проработать учебник Objective-C. В книге есть такой пример:

@interface
{
 int width;
 int height;
 XYPoint *origin;
}
@property int width, height;

Я подумал: «эй, нет объекта getter / setter для объекта XYPoint. Хотя код работает». Теперь я собираюсь ответить на мой собственный вопрос:).

Я думаю, что это потому, что "origin" уже является указателем, а то, что происходит под капотом с "width" и "height", заключается в том, что будет создан указатель на них ..

Я прав, или я говорю BS :) ??

Я просто не понимаю. вот главное:

#import "Rectangle.h"
#import "XYPoint.h"
int main (int argc, char *argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Rectangle *myRect = [[Rectangle alloc] init];
    XYPoint *myPoint = [[XYPoint alloc] init];

    [myPoint setX: 100 andY: 200];
    [myRect setWidth: 5 andHeight: 8];

    myRect.origin = myPoint; 

    NSLog (@"Rectangle w = %i, h = %i",
           myRect.width, myRect.height); 

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

    NSLog (@"Area = %i, Perimeter = %i",
           [myRect area], [myRect perimeter]);

    [myRect release];
    [myPoint release];
    [pool drain];

    return 0;
}

А вот объект Rectangle:

#import "Rectangle.h"
#import "XYPoint.h"

@implementation Rectangle
@synthesize width, height;

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

- (void) setOrigin: (XYPoint *) pt
{
    origin = pt;
}
-(int) area
{
    return width * height;
}
-(int) perimeter
{
    return (width + height) * 2;
}
-(XYPoint *) origin
{
    return origin;
}
@end

Что я не понимаю, так это строки в основном: myRect.origin = myPoint; Я не создал для нее сеттер ..

Кстати, спасибо за быстрый ответ

Ответы [ 5 ]

23 голосов
/ 11 апреля 2010

Что я не понимаю, так это строка в основном: myRect.origin = myPoint; Я не сделал для него сеттер ..

Там - это и геттер, и сеттер (вместе именуемые accessors ), созданные для origin в классе Rectangle. Если вы посмотрите в реализации для Rectangle, это геттер:

-(XYPoint *) origin
{
    return origin;
}

и это сеттер:

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

А по состоянию на Objective-C 2.0 вызов:

myRect.origin = myPoint;

эквивалентно:

[myRect setOrigin:myPoint];

Объявление методов получения и установки с использованием @property (а затем их реализация с использованием @synthesize) - это только один из способов объявления и создания методов доступа, и он удобен, если у вас есть много свойств, которые можно объявить в интерфейсе класса. Как сказал Schildmeijer, @property int width эквивалентно объявлению двух методов:

- (int)width;
- (void)setWidth:(int)newWidth;

Из-за динамически связанной природы вызовов методов Objective C у вас даже нет для объявления методов getter и setter в интерфейсе, хотя обычно это рекомендуется делать, если Вы рекламируете их как общедоступные для других классов.

6 голосов
/ 11 апреля 2010

Вы можете считать объявление свойства эквивалентным объявлению двух методов доступа. Таким образом

@property int width;

эквивалентно:

- (int)width;

- (void)setWidth:(int)newWidth;
1 голос
/ 13 марта 2015
//Rectangle.h
#import <Foundation/Foundation.h>
@interface Rectangle : NSObject
@property int Width;
@property int Height;
-(int)Area;
@end

//Rectangle.m
#import "Rectangle.h"
@implementation Rectangle
@synthesize Width;/*Will create value Width , Setter called"setWidth" and Getter called "Width"*/
@synthesize Height;/*Will create value Height , Setter called"setHeight" and Getter called "Height"*/

-(int)Area
{
    return Width*Height;
}
@end


//  main.m
#import <Cocoa/Cocoa.h>
#import "Rectangle.h"
int main(int argc, const char * argv[])
{
    Rectangle *myRectangle = [Rectangle new];

    myRectangle.Width=3;
    myRectangle.Height=5;
    printf("Area = %d\n",[myRectangle Area]);

    //Or
    [myRectangle setWidth:5];
    [myRectangle setHeight:6];
    printf("Area = %d\n",[myRectangle Area]);

}

Если вы хотите сделать только Getter или переименовать getter и setter

• только для чтения

• getter = newGetterName

• setter = new SetterName

Пример

//Rectangle.h
#import <Foundation/Foundation.h>
@interface Rectangle : NSObject
@property (getter = getWidth) int Width;
@property (readonly) int Height;
@end
0 голосов
/ 11 апреля 2010

Методы получения и установки в основном полезны, если вам нужен доступ к переменной экземпляра из другого класса или вы используете привязки для их получения / установки. Поэтому я предполагаю, что вам нужна эта функциональность для ширины и высоты, а не для источника. Обратите внимание, что получатели / установщики не делают указатели из целых чисел, как вы сказали, может быть причиной. Интты - это целые, а получатели / установщики не меняют это.

0 голосов
/ 11 апреля 2010

Вы не говорите, какой код работает или каковы ваши ожидания в отношении "работы".

Приведенный выше интерфейс создаст простые методы доступа для ширины и высоты, которые можно вызывать из других объектов как [object setWidth:1]; или object.width = 1; - эти два аналога.

Origin - это какой-то другой тип объекта и указатель, да. Но вы все равно захотите объявить свойство, чтобы оно генерировало методы доступа.

...