我正在开发一个具有下载书籍功能的 iPad 应用程序。书籍大小约为 180 个月。书籍在服务器中,扩展名为 .zip。我下载了这本书 (.zip),然后解压缩,然后删除 .zip。我正在这样做:
- (BOOL)downloadBookWithRequest:(BookDownloadRequest*)book
{
if (![book isValid])
{
NSLog(@"Couldn't launch download since request had missing parameter");
return NO;
}
if ([self bookIsCurrrentlyDownloadingWithID:book.ID]) {
NSLog(@"Book already downloaded");
return NO;
}
ASIHTTPRequest *download = [[ASIHTTPRequest alloc] initWithURL:book.URL];
download.userInfo = book.dictionary;
download.downloadDestinationPath = [self downloadPathForBookID:book.ID];
download.downloadProgressDelegate = self.downloadVC.downloadProgress;
download.shouldContinueWhenAppEntersBackground = YES;
[self.downloadQueue addOperation:download];
[download release];
// Update total requests
self.requestsCount++;
[self refreshDownloadsCount];
if(self.downloadQueue.isSuspended)
[self.downloadQueue go];
[self.downloadVC show];
return YES;
}
- (void)requestFinished:(ASIHTTPRequest*)request
{
NSString *bookStoragePath = [[BooksManager booksStoragePath] stringByAppendingPathComponent:request.downloadDestinationPath.lastPathComponent.stringByDeletingPathExtension];
NSString *bookZipPath = request.downloadDestinationPath;
// Tell not to save the zip file into iCloud
[BooksManager addSkipBackupAttributeToItemAtPath:bookZipPath];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *removeExistingError = nil;
if ([fileManager fileExistsAtPath:bookStoragePath])
{
[fileManager removeItemAtPath:bookStoragePath error:&removeExistingError];
if (removeExistingError)
{
[self bookDidFailWithRequest:request errorMessageType:DownloadErrorTypeFILE_ERROR];
NSLog(@"ERROR: Couldn't remove existing book to unzip new download (%@)", removeExistingError);
} else
NSLog(@"INFO: Removed existing book to install new download");
}
ZipArchive* zip = [[ZipArchive alloc] init];
if([self isCompatibleWithFileAtPath:bookZipPath] && [zip UnzipOpenFile:bookZipPath])
{
BOOL unzipSucceeded = [zip UnzipFileTo:bookStoragePath overWrite:YES];
if (!unzipSucceeded)
{
[self bookDidFailWithRequest:request errorMessageType:DownloadErrorTypeFILE_ERROR];
NSLog(@"ERROR: Couldn't unzip file %@\n to %@",bookZipPath,bookStoragePath);
} else {
[self bookDidInstallWithRequest:request];
NSLog(@"INFO: Successfully unziped downloaded file");
}
[zip UnzipCloseFile];
}
else
{
[self bookDidFailWithRequest:request errorMessageType:DownloadErrorTypeFILE_ERROR];
NSLog(@"ERROR: Unable to open zip file %@\n",bookZipPath);
}
[self removeZipFileAtPath:bookZipPath];
[zip release];
}
-(BOOL) removeZipFileAtPath:(NSString*) bookZipPath {
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:bookZipPath])
{
NSError *removeZipFileError = nil;
[fileManager removeItemAtPath:bookZipPath error:&removeZipFileError];
if (removeZipFileError) {
NSLog(@"ERROR: Couldn't remove existing zip after unzip (%@)", removeZipFileError);
return NO;
}
else {
NSLog(@"INFO: Removed zip downloaded after unzip");
return YES;
}
}
return NO;
}
我的问题是:此代码在 iPhone 4/iPhone 4s/iPad 2G/iPad3G 上运行良好,但在第一代 iPad 上崩溃(解压缩书时),崩溃记者说这是内存警告。
问题是,我如何优化此代码以避免内存警告并避免崩溃?感谢您的回答;
编辑:我发现问题是由这部分代码引起的:
NSData *bookData = [[NSData alloc]initWithContentsOfFile:bookPath];
bookPath 是 .zip 的路径(大约 180 Mo),当我在 iPad 1G 中时,这条线会导致我的应用程序崩溃,即:我收到内存警告并且系统会终止应用程序。你知道我怎么能避免这种情况。我使用这条线来计算书的 MD5 (.zip)
我在 NSData 中有一个这样的类别:
#import <CommonCrypto/CommonDigest.h>
@implementation NSData(MD5)
- (NSString*)MD5
{
// Create byte array of unsigned chars
unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
// Create 16 byte MD5 hash value, store in buffer
CC_MD5(self.bytes, self.length, md5Buffer);
// Convert unsigned char buffer to NSString of hex values
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x",md5Buffer[i]];
return output;
}
我怎样才能避免崩溃?谢谢