Почему переменная экземпляра (очевидно) не установлена ​​в nil при инициализации? - PullRequest
0 голосов
/ 19 марта 2012

Я понимаю, что в Objective C 'переменные экземпляра всегда инициализируются в 0 (или nil, NULL или false, в зависимости от точного типа данных)'. stackoverflow вопрос

В модульном тесте 2 ниже, почему переменная экземпляра _willBeRipeBy в оранжевом экземпляре Fruit не установлена ​​на nil? Это терпит неудачу в STAssertNil([orange willBeRipeBy],nil).

test2 проходит, если я создаю метод init для явного задания _willBeRipeBy равным nil или если я переименую test1 в test3 для изменения порядка выполнения.

Создание apple в test1, похоже, влияет на память, которую orange использует, но почему Fruits init не сбрасывает переменную экземпляра в nil.

Я новичок в цели C, спасибо.

(с использованием Xcode 4.3, iOS5.0 с автоматическим подсчетом ссылок)

@interface Fruit : NSObject
- (NSDate *)getWillBeRipeBy;
- (void)setWillBeRipeBy:(NSDate *)ripeBy;
@end

@implementation Fruit

NSDate *_willBeRipeBy;

- (NSDate *)getWillBeRipeBy{
    return _willBeRipeBy;
}
- (void)setWillBeRipeBy:(NSDate *)ripeBy{
    _willBeRipeBy = ripeBy;
}
@end

@implementation TestIvarInitialisationTests

- (void)test1
{
    Fruit *apple = [[Fruit alloc] init];
    STAssertNil([apple getWillBeRipeBy],nil);
    NSDate * now = [NSDate date];
    [apple setWillBeRipeBy:now];
    STAssertEqualObjects([apple getWillBeRipeBy], now,nil);
}

- (void)test2
{
    Fruit *orange = [[Fruit alloc] init];
    STAssertNil([orange getWillBeRipeBy],nil);
}
@end

Ответы [ 2 ]

4 голосов
/ 19 марта 2012

Вы должны объявить переменную как переменную экземпляра в заголовочном файле или в {} -кобы после директивы @implementation.

Ваша реализация является глобальной переменной

кстати. Вы не должны называть методы, такие как «get ...» - это противоречит соглашениям о присвоении имен какао. Вы должны использовать «get ..» только если вы хотите установить необъектный тип с неизвестным размером, например: CGRect rect; [userInfoDictionary getValue:&rect forKey:@"bla"]
Вы можете использовать свойства (@property(strong) NSString *property и @synthesize property) для автоматической реализации переменных экземпляра вместе с методами получения и установки

2 голосов
/ 19 марта 2012

Поскольку переменные, объявленные внутри блока реализации, не являются переменными экземпляра, они являются глобальными переменными, общими для экземпляров класса.И, по-видимому, глобальные переменные не гарантируются для нормального значения.

Ваш класс Fruit должен выглядеть следующим образом:

@interface Fruit : NSObject
@property(strong) NSDate *willBeRipeBy;
@end

@implementation Fruit
@synthesize willBeRipeBy;
@end
...