Как этот объект преждевременно выпущен? - PullRequest
1 голос
/ 26 сентября 2010

Я получил отчет о сбое от Apple, и я пытаюсь определить, что произошло.Я не смог воссоздать сбой, выполнив их действия, и я не видел подобного сбоя ни в одном из своих тестов.Вот важные части отчета о сбое:

9   libobjc.A.dylib                 0x00004838 objc_exception_throw + 64
10  CoreFoundation                  0x000a167c -[NSObject(NSObject) doesNotRecognizeSelector:] + 96
11  CoreFoundation                  0x000491d2 ___forwarding___ + 502
12  CoreFoundation                  0x00048f88 _CF_forwarding_prep_0 + 40
13  TheApp                          0x0001cd28 -[Tumblelog initWithDictionary:] (Tumblelog.m:40)
14  TheApp                          0x0001ef8c -[TumblrEngine userFromRequest:] (TumblrEngine.m:589)

Мне кажется, что мой словарь преждевременно выпущен.Этот путь к коду вызывается несколько раз во время большинства запусков приложения, и он еще не сработал для меня, поэтому я уверен, что не случайно отправил неправильный объект на initWithDictionary.

Здесьэто код из TumblrEngine и Tumblelog.

// TumblrEngine.m
- (TumblrUser *)userFromRequest:(ASIHTTPRequest *)request{
    NSData *data = [request responseData];
    NSError *parseError = nil;
    NSXMLDocument *doc = [[[NSXMLDocument alloc] initWithData:data options:NSXMLDocumentTidyXML error:&parseError] autorelease];
    NSDictionary *dictionary = [doc toDictionary];
    NSDictionary *userDict = [dictionary valueForKeyPath:kParseKeyPathUserInfo];
    TumblrUser *user = [[TumblrUser alloc] initWithDictionary:userDict];
    NSArray *tumblelogs = [dictionary valueForKeyPath:kParseKeyPathTumblelogsInfo];
    NSMutableArray *userTumblelogs = [NSMutableArray array];
    for(NSDictionary *tumblelogDictionary in tumblelogs){
        Tumblelog *tumblelog = [[Tumblelog alloc] initWithDictionary:tumblelogDictionary]; //line 589
        [userTumblelogs addObject:tumblelog];
        [tumblelog release];
    }
    [user setTumblelogs:userTumblelogs];
    return [user autorelease];

}

// Tumblelog.m
- (id)initWithDictionary:(NSDictionary *)aDictionary{
    if((self = [super init])){
        [self setAvatarURL:[aDictionary restURLForKey:kParseKeyTumblelogAvatarURL]]; //line 40
        // this was the line that started the crash
    }
    return self;
}

Мой главный вопрос: видите ли вы, как было бы возможно для aDictionary быть выпущенным в любой момент между его созданием и когдаЯ пытаюсь использовать его в Tumblelog.m?

В противном случае, я исследую, есть ли проблема с загрузкой категории на NSDictionary.Он отлично работает, когда я напрямую загружаю приложение на три тестовых телефона (iPhone 4 / iOS 4.1, iPhone 3GS / iOS 4.0.1, iPhone 3G / 3.1.3).Телефон, на котором упало приложение, был iPhone 4 / iOS 4.1, идентичный моему основному тестовому телефону.

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

1 Ответ

1 голос
/ 27 сентября 2010

Это может быть проблема с многопоточностью (когда объекты освобождаются в другом потоке), но это кажется маловероятным с приведенным выше кодом.

Скорее всего (как говорит @imaginaryboy), что у вас нет словаря.

Гораздо более безопасный цикл выглядел бы так:

for(id tumblelogDictionary in tumblelogs){
    if ([tumblelogDictionary isKindOfClass:[NSDictionary class]]) {
        Tumblelog *tumblelog = [[Tumblelog alloc] initWithDictionary:tumblelogDictionary]; //line 589
        [userTumblelogs addObject:tumblelog];
        [tumblelog release];
    } else {
        // Appropriate error handling and / or logging.
    }
}

ПРИМЕЧАНИЕ. На самом деле я не пытался это скомпилировать. Это может быть опечатка или синтаксическая ошибка или два.

...