Как в Objective-C вы настраиваете свойства свойств, то есть класса, настроенного как другое свойство класса? - PullRequest
0 голосов
/ 24 июля 2010

Я пытался настроить свойство экземпляра класса, который сам является классом, который содержит переменные экземпляра. Я хотел бы получить доступ к этим как свойства. В C # это легко сделать с помощью предварительно установленных переменных get и set:

public class TheOverallClass
{
    private ClassName _propertyName;
    public ClassName PropertyName
    {
        get { return _propertyName; }
        set { _propertyName = value; }
    }

... и PropertyName создается в конструкторе:

    public TheOverallClass()
    {
        PropertyName = new ClassName();
    }
}

Скажем, у PropertyName есть переменная / свойство экземпляра с именем ThisValue, после чего я могу получить к нему доступ:

TheOverallClass overallClass = new TheOverallClass();
overallClass.PropertyName.ThisValue = 20;    // int
Console.WriteLine(overallClass.PropertyName.ThisValue.ToString());

Как бы я поступил так в Objective-C? Я попробовал, но столкнулся с трудностями.

Эквивалент PropertyName кодируется как:

... в AnotherClass.h:

@interface AnotherClass : NSObject {
    int thisValue;
}
@property (readwrite,assign) int ThisValue;
@end

... и в AnotherClass.m

@implementation AnotherClass
@synthesize ThisValue=thisValue;
@end

Это затем используется в эквиваленте ClassName, MyClass:

... в MyClass.h:

@class AnotherClass;
@interface MyClass : NSObject {
    AnotherClass* another;
}
@property (nonatomic,retain) AnotherClass* Another;
@end

... и в MyClass.m:

@implementation MyClass
@synthesize Another=another;
@end

Когда я пытаюсь получить / установить значения в коде, XCode возвращает «Доступ к неизвестному компоненту ThisValue свойства». Код, который я использую для доступа:

MyClass* me = [[MyClass alloc] init];
me.Another.ThisValue = 20;
NSLog(@"Value = %i", me.Another.ThisValue);

Что я делаю не так?

Ответы [ 4 ]

0 голосов
/ 23 августа 2011

Я также пришел из .NET-фона и вижу, что вы пытаетесь сделать.

Я думаю, вы также можете попробовать это (чтобы получить больше поведения на C #):

.h Файл

@class AnotherClass;
@interface MyClass : NSObject {
    AnotherClass* another;
}
@property (nonatomic,retain) AnotherClass* Another;
@end

.m Файл

@implementation MyClass
@synthesize Another=another;

// Implementing a custom accessor
- (AnotherClass *)Another
{
    if (!another) {
        AnotherClass *other = [[AnotherClass alloc] init];
        another = other;
    }
    return another;
}
@end

Таким образом, вы обязательно создадите свойство независимо от того, сделали ли вы это самостоятельно или нет.Затем вы можете реализовать значение по умолчанию в методе init AnotherClass.

Я знаю, что это нарушает шаблоны кодирования Objective-C, но это способ заставить его "работать".:)

0 голосов
/ 24 июля 2010

Ваш код должен работать:

// main.m


#import <Foundation/Foundation.h>

@interface AnotherClass : NSObject {
    int thisValue;
}
@property (readwrite,assign) int ThisValue;
@end

@implementation AnotherClass
@synthesize ThisValue=thisValue;
@end

@interface MyClass : NSObject {
    AnotherClass* another;
}
@property (nonatomic,retain) AnotherClass* Another;
@end

@implementation MyClass
@synthesize Another=another;
@end


int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // insert code here...

    MyClass* me = [[MyClass alloc] init];
    me.Another.ThisValue = 20;
    NSLog(@"Value = %i", me.Another.ThisValue);


    [pool drain];
    return 0;
}

Независимо от соглашений о кодировании, этот код компилируется и работает просто отлично.

0 голосов
/ 24 июля 2010

Предполагая, что код, который обращается к свойству, находится в main.m, как уже упоминалось, вам понадобится оператор import для класса, который объявляет свойство (в данном случае AnotherClass.h). Но ваш код все равно не будет работать так, как вы ожидаете, потому что он никогда не создает вложенный экземпляр AnotherClass. Попробуйте это:

MyClass* me = [[MyClass alloc] init];
me.Another = [[AnotherClass alloc] init];
me.Another.ThisValue = 20;
NSLog(@"Value = %i", me.Another.ThisValue);

Тогда сделайте себе одолжение и не изменяйте имена свойств в ваших утверждениях @synthesize. Вместо этого ...

@synthesize ThisValue=thisValue;

... просто сделай это ...

@synthesize thisValue;

... а затем переписать код в main следующим образом ...

MyClass* me = [[MyClass alloc] init];
me.another = [[AnotherClass alloc] init];
me.another.thisValue = 20;
NSLog(@"Value = %i", me.another.thisValue);
0 голосов
/ 24 июля 2010

Включаете ли вы AnotherClass.h в файл, содержащий me.Another.ThisValue = 20;? Если нет, он не будет знать, как обращаться с Another классом.

(Кроме того, инициалы в верхнем регистре обычно зарезервированы для констант и имен классов, в отличие от C #.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...