0

I am having a crash I do not understand. I am downloading a couple files from a remote server, and when a file has finished downloading, I am attempting to retrieve an object that was attached to the request object.

Tia for any help!

S.

Main Class

for (TrainingEntry* _entry in objects) {

    HTTPRequest * request = [HTTPRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", [[ConfigLoader config] objectForKey:@"Server"], _entry.url]]];
    [request setDownloadDestinationPath:[NSString stringWithFormat:@"%@/%@", documentsDirectoryPath, _entry.filename]];

    [request setEntry:_entry];
    [request setRaw:_entry.title];

    TrainingEntry * test = (TrainingEntry*)[request _entry];
    NSLog(@"title: %@", [test title]); //<= This works
    NSLog(@"filename: %@", [test filename]); //<= This works

    [[self networkQueue] addOperation:request];

}

// Start Queue
[[self networkQueue] go];

...
- (void)requestFinished:(HTTPRequest *)request {

    if ([[self networkQueue] requestsCount] == 0) {
        [self setNetworkQueue:nil]; 
    }

    NSLog(@"req: %@", [request raw]);
    NSLog(@"title: %@", [[request entry] title]); // <= This works
    NSLog(@"filename: %@", [[request entry] filename]); // <= This crashes

}

HTTPRequest Object

@interface HTTPRequest : ASIHTTPRequest {

}

@property (nonatomic, retain) TrainingEntry * entry; 
@property (nonatomic, retain) NSString * raw;

@end

TrainingEntry Class

@interface TrainingEntry : NSObject {
    NSString * title;   
    NSString * filename;
}

@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSString * filename;
Soch S.
  • 653
  • 6
  • 23
  • Where do you set `filename` and how is that string you set it to treated? – Georg Fritzsche Dec 02 '10 at 17:50
  • You definitely synthesizing NSString* filename? Also what is the HTTPRequest class, is this a subclass of NSURLRequest? Can you set a breakpoint before the crash and print your request object to the console? If so can you see if the filename string has been there? – Rog Dec 02 '10 at 17:55
  • HTTPRequest is a subclass of ASIHTTPRequest which is a library available from http://allseeing-i.com/ASIHTTPRequest/ Here are 2 images show the initial TrainingEntry object, and the TrainingEntry object returned after the requestFinished: is triggered. Before: http://shareimage.org/images/a0b0cfr2znyi2sylju9.jpg After: http://shareimage.org/images/vereup03afwwzr8niym9.jpg – Soch S. Dec 02 '10 at 21:22

2 Answers2

0

Something that may be giving you trouble is not having copy in your property declaration. You should consider using copy for all objects that conform to the NSCopying protocol specification, especially NSString and other collection classes.

In the past, changing retain to copy for an NSString property solved a similar issue for me.

edit: some research

This post may help clarify why you should use copy over retain for immutable objects.

Community
  • 1
  • 1
Hyperbole
  • 3,917
  • 4
  • 35
  • 54
  • `copy` only matters if the string being set is mutable and is mutating after it is set. Otherwise, `retain` and `copy` are effectively identical (`copy`ing an immutable string just returns the same string instance). – bbum Dec 02 '10 at 20:34
  • Indeed, though the property is immutable the value set to it may not be. `copy` should be preferred in case an `NSMutableString` is the parameter to a set operation. http://stackoverflow.com/questions/387959/nsstring-property-copy-or-retain may help clarify this distinction. – Hyperbole Dec 02 '10 at 20:52
  • This has done the trick. Once I added the NSCopying protocol to the TrainingEntry object, and changed my @property from retain to copy, it worked! :) I thank you Hyperbole! – Soch S. Dec 02 '10 at 22:45
  • Hmmm, unless you have a good explanation for *why* that worked, I think you might just be masking some other mistake now. Copy vs retain should net the same as far as memory mgmt except that copy might be masking an over-release of the original (presumably mutable) string. OR masking a leak of some other object that had a reference to the original mutable string. – Firoze Lafeer Dec 03 '10 at 00:22
0

When a crash occurs, there will be a backtrace.

Post it.

Either your program will break in the debugger, and the call stack will be in the debugger UI (or you can type 'bt

With that, the cause of the crash is often quite obvious. Without that, we are left to critique the code.


If this crashes:

NSLog(@"filename: %@", [[request entry] filename]); // <= This crashes

It is either because request has been over-released and is no longer viable or because filename is returning a garbage object. Given that request worked previously, it is likely that filename has been over-released.

Where do you set filename?

bbum
  • 162,346
  • 23
  • 271
  • 359
  • The debugger only showed Program received signal: “EXC_BAD_ACCESS”. Typing bt add: #0 0x01691a63 in objc_msgSend () #1 0x00000000 in ?? () filename is part of the _entry object from the for each loop. The TrainingEntry array is built from a JSON returned object. In the initial method, the filename (and title) are available, but are lost when the object is retrieved in requestFinished:. – Soch S. Dec 02 '10 at 21:04
  • Edit your question to show the initialization of filename and add the backtrace, too. Sounds like stack corruption. – bbum Dec 02 '10 at 23:01