#iphone #objective-c
#iPhone #objective-c
Вопрос:
У меня есть следующий код:
@interface Reservation : RKObject {
NSNumber * _uid;
NSNumber * _did;
NSNumber * _rid;
NSString* _origin;
NSString* _destination;
NSString* _time_range;
NSDate * _start_date;
NSDate * _end_date;
}
@property (nonatomic, retain) NSDate * start_date;
@property (nonatomic, retain) NSDate * end_date;
@property (nonatomic, retain) NSNumber * uid;
@property (nonatomic, retain) NSNumber * did;
@property (nonatomic, retain) NSNumber * rid;
@property (nonatomic, retain) NSString * time_range;
@property (nonatomic, retain) NSString * origin;
@property (nonatomic, retain) NSString * destination;
@end
#import "Reservation.h"
@implementation Reservation
@synthesize time_range= _time_range;
@synthesize origin=_origin;
@synthesize destination=_destination;
@synthesize uid=_uid;
@synthesize did=_did;
@synthesize rid=_rid;
@synthesize start_date=_start_date;
@synthesize end_date=_end_date;
(NSDictionary*) elementToPropertyMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@"TIME_RANGE", @"time_range",
@"ORIGIN_ADDRESS", @"origin",
@"DESTINATION_ADDRESS", @"destination",
@"UID", @"uid",
@"DID", @"did",
@"RID", @"rid",
@"START_DATETIME", @"start_date",
@"END_DATETIME", @"end_date",
nil];
}
/*
(NSDictionary*)elementToRelationshipMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@"NSDate", @"start_date",
@"NSDate", @"end_date",
nil];
}
*/
- (void)dealloc
{
[_start_date release];
[_end_date release];
[_uid release];
[_did release];
[_rid release];
[_origin release];
[_destination release];
[_time_range release];
//[_deal release];
//[_route release];
[super dealloc];
}
@end
@interface ReservationViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, RKObjectLoaderDelegate>{
Reservation * myres;
}
@property (nonatomic, retain) Reservation * myres;
#import "ReservationViewController.h"
@implementation ReservationViewController
@synthesize myres;
- (IBAction)makeReservation:(id)sender
{
self.myres = [[[Reservation alloc] init] autorelease];
myres.start_date = [df dateFromString:[NSString stringWithFormat:@"%@ %@", [self.data objectForKey:@"date"], [self.data objectForKey:@"start_time"]]];
myres.end_date = [df dateFromString:[NSString stringWithFormat:@"%@ %@", [self.data objectForKey:@"date"], [self.data objectForKey:@"end_time"]]];
NSLog(@"date is %@", myres.start_date);
}
- (void)objectLoader: (RKObjectLoader*) objectLoader didLoadObjects:(NSArray *)objects {
Interval * res_int = [[Interval alloc] init];
res_int.date1 = myres.start_date; //why is it null here
res_int.date2 = myres.end_date; //why is it null here
res_int.rid = [[objects objectAtIndex:0] rid];
[[LocationDictionary sharedLocationDictionary] addLocationtoDictionary:[self.data objectForKey:@"route"] withKey:res_int];
}
Вопрос в том, почему res_int.date1
значение равно null, когда я пытался его распечатать? Когда я печатаю myres.start_date внутри метода makeReservation, он печатается соответствующим образом, Может кто-нибудь объяснить мне это и как это исправить?
Обновить:
Я сделал следующее в своем установщике:
-(void) setStart_date:(NSDate *) boo
{
NSAssert(boo != nil, @"why is this nil");
_start_date = boo;
}
в конце я получил трассировку стека:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'why is this nil'
*** Call stack at first throw:
(
0 CoreFoundation 0x019ac5a9 __exceptionPreprocess 185
1 libobjc.A.dylib 0x01b00313 objc_exception_throw 44
2 CoreFoundation 0x01964ef8 [NSException raise:format:arguments:] 136
3 Foundation 0x014013bb -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] 116
4 Project 0x00012d42 -[Reservation setStart_date:] 194
5 Foundation 0x0137e5e5 -[NSObject(NSKeyValueCoding) setValue:forKey:] 285
6 Project 0x0004c7b3 -[RKObjectMapper updateModel:ifNewPropertyValue:forPropertyNamed:] 172
7 Project 0x0004cd55 -[RKObjectMapper setPropertiesOfModel:fromElements:] 754
8 Project 0x0004d8f3 -[RKObjectMapper updateModel:fromElements:] 50
9 Project 0x0004bb7a -[RKObjectMapper mapObject:fromDictionary:] 201
10 Project 0x0004ba42 -[RKObjectMapper mapObject:fromString:] 148
11 Project 0x0004927b -[RKObjectLoader processLoadModelsInBackground:] 537
12 Foundation 0x01370cf4 -[NSThread main] 81
13 Foundation 0x01370c80 __NSThread__main__ 1387
14 libSystem.B.dylib 0x931a085d _pthread_start 345
15 libSystem.B.dylib 0x931a06e2 thread_start 34
)
terminate called after throwing an instance of 'NSException'
Комментарии:
1. -1 Я не вижу здесь никаких глобальных переменных.
2. myres — это глобальная переменная, верно
3. Согласно приведенному выше коду
myres
является переменной-членом класса в `ReservationViewController’. Следовательно, это не глобальное.4. отредактировал заголовок вопроса, пожалуйста, поддержите его еще раз
5. Теперь это больше похоже на неправильное понимание RKObjectMapper, чем на что-либо в управлении памятью.
Ответ №1:
Какова последовательность вызова makeReservation
(из IBAction) и objectLoader
? Возможно ли, что objectLoader
вызывается ранее, makeReservation
поэтому myres
еще не было инициализировано?
Каково определение интерфейса для did
свойства резервирования? Ваша строка:
myres.did = [[NSNumber alloc] initWithInt:[[[data objectForKey:@"discount"] did] intValue]];
Если она определена как (nonatomic, retain)
, возможно, вы сохраняете объект NSNumber, не освобождая его. Если это так, измените строку на:
myres.did = [NSNumber numberWithInt:[[[data objectForKey:@"discount"] did] intValue]];
Вам также следует раскомментировать свою строку:
//[res_int release]
Комментарии:
1. Я выполнил все ваши предложения, и makeReservation вызывается первым перед ObjectLoader … по-прежнему имеет значение null
2. происходит много чего, чего мы не видим в этом примере кода. Например, вы проверили это
myres.start_date != nil
вobjectLoader
после его первого назначения?[df dateFromString:...]
также может произойти сбой. Я бы начал с этого и продвигался вперед, проверяя все предположения по ходу дела. Добавьте несколькоNSLog()
инструкций для вывода значений в консоль отладки.3. просто попытался выполнить myres.start_date внутри ObjectLoader и да, это ноль, но почему?????
4. вам нужно продолжать отладку. итак, теперь вы знаете, что
[df dateFromString:...]
происходит сбой. Разбейте функцию на части и проверьте значения аргументов. Один или несколько из них явно недопустимы, поэтому где-то в процессе вы что-то неправильно настраиваете. Опять же, я бы начал с самого начала. Например. где присвоены самые первые значения, проверьте, работает ли это. Затем перейдите к следующему шагу и т.д. В конце концов вы найдете точное место, где он ломается, и тогда «почему» должно стать ясно.5. кроме того, где вы выделяете и настраиваете
df
? Я предполагаю, что это экземпляр NSDateFormatter. Попробуйте[df dateFromString:@"REPLACE_WITH_YOUR_SAMPLE_DATE_STRING"]
и используйте допустимую строку, которую вы ожидаете от своих аргументов. Это работает? Проверьте каждый аргумент, который вы используете для построения строки даты. Они правильные? И т.д. и т.п. Это просто стандартная отладка. Вы обнаружите проблему.
Ответ №2:
в вашем методе сохранения makeReservation попробуйте следующее:
self.myres = [[[Reservation alloc] init] autorelease];
При этом сохранится объект резервирования.
Редактировать: XJones прав. Редактирование строки кода.
Комментарии:
1. На самом деле, хорошей практикой является называть ваши переменные как-то иначе, чем имя вашего свойства, чтобы избежать путаницы. Итак, что-то вроде резервирования @property (неатомное, сохранить) * myres; @synthesize myres = _myres;
2. это неправильно. свойство
myres
определено как «сохранить», поэтому ваша строка кода должна быть такой,self.myres = [[[Reservation alloc] init] autorelease]
иначе экземпляр будет сохранен дважды (один раз с помощью alloc и еще раз с помощьюmyres
установщика свойств). Или просто оставьте все так, как у вас есть. Вы выделяете myres непосредственно в iVar, поэтому он уже сохраняется должным образом. Я согласен с @Micah Hainline относительно именования.3. Вы уверены, что dateFromString в makeReservation указывает правильную дату?
4. Я распечатал myres.start_date в функции makeReservation, и она выводит дату.. когда я печатаю myres.start_date в методе ObjectLoader, оно равно нулю
5. В ObjectLoader значение myres равно нулю или просто значение start_date равно нулю? Если это просто start_date nil, я не уверен, почему значение не сохраняется, поскольку вы подтвердили ниже, что это свойство с ‘retain’ .
Ответ №3:
Ваша проблема, скорее всего, в Reservation.h
.
Убедитесь, что для ваших дат указано следующее:
@property (non-atomic, retain) NSDate *start_date;
@property (non-atomic, retain) NSDate *end_date;
Атрибутом импорта здесь является сохранить.
Комментарии:
1. и интервал класса такой же для свойства date1 amp; date2?
2. Ну, я бы добавил немного NSLog в метод makeReservation, чтобы увидеть, что равно null. Используется NSAssert. Например:
NSLog(@"Date Formatter: %@", df);
,NSLog(@"Data Date: %@", [self.data objectForKey:@"date"]);
и т. Д3. поскольку я отредактировал вопрос выше … myres.start_date не равен нулю при сохранении makeReservation
4. И когда вы достигнете метода ObjectLoader, вы уверены
myres != nil
?5. значение myres не равно нулю, но значение myres.start_date равно нулю… теперь вопрос в том, почему