NSNumber выходит за рамки? - PullRequest
1 голос
/ 26 мая 2009

Я написал класс Objective-C и использую его общий экземпляр для нескольких представлений в моем проекте iPhone. Его переменные-члены включают в себя bools, ints, NSStrings и один NSNumber. Общий экземпляр, кажется, прекрасно работает во всей области моего приложения, за исключением NSNumber, который, как говорит отладчик, «выходит за рамки», когда к общему экземпляру обращаются во 2-й или последующий раз.

Вот краткий обзор того, что я делаю ...

// UserData.h
@interface UserData : NSObject {
    TaxYears selectedTaxYear;
    NSNumber *grossWage; // <--- this is the troublesome member

// ...

    NSString *other;
    int age;

}
+ (UserData *)getSharedUserData;

@end

// UserData.m
#import "UserData.h"

@implementation UserData

static UserData *sharedUserData = nil;  // Points to the shared object

+ (UserData *)getSharedUserData {
    if(sharedUserData == nil) {
        sharedUserData = [[UserData alloc] initWithTaxYear:0];
        [[NSNotificationCenter defaultCenter]
         addObserver:sharedUserData
         selector:@selector(doTerminate:)
         name:UIApplicationWillTerminateNotification
         object:nil];
    }
    return sharedUserData;
}

- (id)initWithTaxYear:(TaxYears)theTaxYear {
    if ((self = [super init])) {

    }
    return self;
}
- (void)updateGrossWage:(NSNumber *)theGrossWage {
    grossWage = theGrossWage;
}
- (NSNumber *)getGrossWage {
    return grossWage;
}
// ...
@end

Таким образом, к нему обращаются в одном представлении, как это:

UserData *userData
userData = [[UserData getSharedUserData] retain];

И в другом виде точно так же. Но во второй раз, когда к нему обращаются, член grossWage выходит за рамки, но все остальное в порядке - вот почему я в тупике. Есть идеи?

Ответы [ 4 ]

4 голосов
/ 26 мая 2009

Почему вы пишете grossWage аксессоры (updateGrossWage и getGrossWage) вручную? И вы уверены, что просто хотите назначить данную брутто-зарплату вместо ее сохранения или копирования? Таким образом, когда вызывающий абонент избавится от своего экземпляра брутто-зарплаты, вы получите освобожденную брутто-зарплату в объекте userData:

NSNumber grossWage = [[NSNumber numberWithInt:12] retain];
[userData updateGrossWage:grossWage];
[grossWage release];
// Now userData’s grossWage points to released object.

Это может быть причиной проблемы. Если нет, я бы предложил опубликовать меньший фрагмент полного примера кода - без уведомления и с контекстом вызова.


P.S. Такие общие объекты, как ваш UserData, обычно вредны для вашего дизайна (= это приводит к боли в коде), см., Например, эту статью Мишко Хевери и другие статьи в его блоге.

2 голосов
/ 26 мая 2009

Причина, по которой у вас возникают проблемы, не в том, что вы должны или не должны использовать свойство, а в том, что вы не следуете правилам управления памятью. NSNumber - это объект, который должен быть сохранен в вашем установщике. Изменение его на свойство решит непосредственную проблему, потому что Objective-C выполняет эту работу за вас, но вы все равно должны пересмотреть управление памятью, потому что вы на 100% уверены, что у вас по-прежнему будут проблемы, пока вы не освоитесь с этим.

0 голосов
/ 26 мая 2009

Звучит глупо, но проверяйте деление на ноль. У меня была та же ошибка, и причиной было деление на ноль.

0 голосов
/ 26 мая 2009

Отслеживание точки @ zoul ...

Я бы объявил, что grossWage - это свойство, и синтезировал бы методы получения и установки. Я думаю, что сеттер является источником вашей проблемы.

// in UserData.h
@interface UserData : NSObject {
    NSNumber *grossWage; 
}

@property (nonatomic, retain) NSNumber *grossWage; 



// in UserData.m
#import "UserData.h"

@implementation UserData
@synthesize grossWage;

// then do NOT create getters and setters for grossWage

Посмотрите, не прояснит ли это.

...