Reputation: 16059
I have a UserService
singleton that contains the following method. I am getting an EXC_BAD_ACCESS on the line that sets book.downloaded
in the progress callback.
I want the service to continue to download and update the book object even if the user exits the view they are on (currently a detail view for a table). It all works fine if I keep the detail view open, but when I back out to the parent table view, I get the bad access.
My first thought was that book
is being released by ARC, but that doesn't hold water. You can set other properties, and even read the current value of book.downloaded
, but the minute you try to set it. Boom.
Book
is a CoreData class generated by mogenerator, if it matters.
// UserService is a singleton.
// Only errors if I back out of the detail view to the parent table view.
-(void)addBook:(Book *)book downloadProgress:(void (^)(Book *))progressCb downloadComplete:(void (^)(Book *))cb {
book.purchasedValue = YES;
book.downloadedValue = 0.0;
// making my UserService own the book with a strong reference doesn't help
self.strongBookProperty = book;
[FileService.shared
downloadFiles:[FileService.shared byBookId:book.bookId]
progress:^(float percent) {
book.title = @"fake title"; // no error!
NSLog(@"old downloaded %@", book.downloaded); // no error!
book.downloaded = [NSNumber numberWithFloat:percent]; // EXC_BAD_ACCESS
progressCb(book);
}
complete:^() {
book.downloaded = [NSNumber numberWithFloat:1.0];
cb(book);
}
];
}
UPDATE I am key-value observing book.downloaded
in the details view that kicks this off. If I comment out the key-value observation it doesn't error. Why? (Obviously this makes my view not update). This explains why only that property was throwing an error (it's the only one being key-value observed).
Upvotes: 0
Views: 316
Reputation: 16059
I was not removing my key-value observers on book in the dealloc
method of my details view. The following got rid of the error. (In the details view)
-(void)dealloc {
[self.book removeObserver:self forKeyPath:@"downloaded"];
[self.book removeObserver:self forKeyPath:@"purchased"];
}
I thought ARC would take care of that for me, but I it sort of makes sense that it wouldn't know how. I also don't really understand how that would cause a bad access on the line I was getting it. It seems like it would give a bad access in the dealloced observer instead.
Upvotes: 1