我正在尝试从用户的相机胶卷中检索图像,但我遇到了内存不足的问题。我一次加载50个图像,但不幸的是,在几次加载后,它耗尽内存并崩溃。我试过在autoreleasepool中包装整个语句,但事实证明这是无效的。这是我的代码......
func retrieveImages(thumbnail: Bool, indexOfLibrary: Int) {
/* Retrieve the items in order of modification date, ascending */
var indexSet: NSIndexSet!
let options = PHFetchOptions()
options.sortDescriptors = [NSSortDescriptor(key: "creationDate",
ascending: false)]
/* Then get an object of type PHFetchResult that will contain
all our image assets */
let assetResults = PHAsset.fetchAssetsWithMediaType(.Image,
options: options)
if totalPostsCounted == false {
assetResults.enumerateObjectsUsingBlock { (object: AnyObject!, count: Int, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
if object is PHAsset {
self.totalPosts = count
} else {
self.totalPostsCounted = true
}
}
}
if thumbnail == true {
if totalPosts - libraryImageThumbnails.count < 50 {
allImagesLoaded = true
} else {
if firstTimeLoadedThumb == true {
} else {
firstTimeLoadedThumb = true
}
}
} else {
if totalPosts - libraryImages.count < 50 {
allImagesLoaded = true
} else {
if firstTimeLoaded == true {
} else {
firstTimeLoaded = true
}
}
}
if thumbnail == true {
fiftyIncrementThumb = fiftyIncrementThumb + 50
increment = fiftyIncrementThumb
} else {
fiftyIncrement = fiftyIncrement + 50
increment = fiftyIncrement
}
let imageManager = PHCachingImageManager()
autoreleasepool { () -> () in
assetResults.enumerateObjectsUsingBlock { (object, count: Int, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
if object is PHAsset {
var imageSize: CGSize!
var array: NSArray!
if thumbnail == true {
array = self.libraryImageThumbnails
} else {
array = self.libraryImages
}
autoreleasepool {
if count >= array.count && count <= increment {
if thumbnail == true {
imageSize = CGSize(width: 100, height: 100)
} else {
imageSize = CGSize(width: self.cameraView.bounds.width, height: self.cameraView.bounds.height)
}
let asset = object as! PHAsset
let options = PHImageRequestOptions()
options.deliveryMode = .FastFormat
options.synchronous = true
imageManager.requestImageForAsset(asset,
targetSize: imageSize,
contentMode: .AspectFill,
options: options,
resultHandler: { (image, _: [NSObject : AnyObject]?) -> Void in
if thumbnail == true {
self.libraryImageThumbnails.append(image!)
} else {
self.libraryImages.append(image!)
}
})
}
}
}
}
}
}
我也试过了,它返回了nil并崩溃了......
let library = ALAssetsLibrary()
library.enumerateGroupsWithTypes(ALAssetsGroupAll, usingBlock: { (group: ALAssetsGroup!, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
group.enumerateAssetsUsingBlock({ (asset, count: Int, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
if asset != nil {
self.libraryImageThumbnails.append(asset)
self.collectionTable.reloadData()
}
})
}, failureBlock: { (error: NSError!) -> Void in
})
告诉我您是否需要更多信息!谢谢!
答案 0 :(得分:2)
这是我在一个可能有帮助的项目中所做的事情:
一些属性:
let requestOptions = PHImageRequestOptions()
let fetchOptions = PHFetchOptions()
let cachingImageManager = PHCachingImageManager()
var assets: [PHAsset] = [] {
willSet {
cachingImageManager.stopCachingImagesForAllAssets()
}
didSet {
cachingImageManager.startCachingImagesForAssets(assets,
targetSize: PHImageManagerMaximumSize,
contentMode: .AspectFit,
options: self.requestOptions
)
}
}
func fetchPhotos() {
requestOptions.resizeMode = PHImageRequestOptionsResizeMode.Exact
requestOptions.version = .Current
requestOptions.deliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat
requestOptions.synchronous = true
fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending: false)]
if #available(iOS 9.0, *) {
fetchOptions.fetchLimit = 50
} else {
// Fallback on earlier versions
}
fetchResults = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: fetchOptions)
guard let fetchResults = fetchResults else {
print("No PHAssets")
return
}
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) { [weak self] in
fetchResults.enumerateObjectsUsingBlock{ object, index, stop in
let asset = object as! PHAsset
self?.assets.append(asset)
}
dispatch_async(dispatch_get_main_queue()) {
self?.photoCollectionView.reloadData()
}
}
}
答案 1 :(得分:1)
尝试使用此代码并确保导入NSMutableArray *imageArray=[[NSMutableArray alloc] init];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop)
{
if (asset) {
[imageArray addObject:asset];
NSLog(@"imageArray :: %@",imageArray);
}
}];
} failureBlock:^(NSError *error) {
NSLog(@"error :: %@",error);
}];
并使部署目标为7.1。
目标-C代码
var imageArray: [AnyObject] = [AnyObject]()
var library: ALAssetsLibrary = ALAssetsLibrary()
library.enumerateGroupsWithTypes(ALAssetsGroupSavedPhotos, usingBlock: {(group: ALAssetsGroup, stop: Bool) -> Void in
group.enumerateAssetsUsingBlock({(asset: ALAsset, index: Int, stop: Bool) -> Void in
if asset != nil {
imageArray.append(asset)
NSLog("imageArray :: %@", imageArray)
}
})
}, failureBlock: {(error: NSError) -> Void in
NSLog("error :: %@", error!)
})
Swift代码
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<sys/types.h>
void main()
{
struct sockaddr_in server;
int sock;
char buffer[20];
printf("Enter a string :");
scanf("%s",buffer);
server.sin_family = AF_INET;
server.sin_port = 2000;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
sock = socket(AF_INET,SOCK_STREAM, 0);
connect(sock, (struct sockaddr*) &server, sizeof(server));
send(sock, buffer, sizeof(buffer), 0);
recv(sock, buffer, sizeof(buffer), 0);
printf("The reverse string is: %s",buffer);
printf("\n");
}
检查以下网址以供参考
https://stackoverflow.com/a/15570221/4101371
https://stackoverflow.com/a/25732673/4101371
https://stackoverflow.com/a/32472476/4101371
您还可以使用iOS 8以上的照片框架。 photos Framework
希望它会有所帮助。
答案 2 :(得分:1)
设置下面的代码对我来说有限制了提取
let assetFetchOptions = PHFetchOptions()
assetFetchOptions.fetchLimit = 50
然后我在朋友的手机上只检索了50张相对于15,000张的照片!!