我可能会以错误的方式提出我的问题,并且完全被stackoverflow阻止。我有Asperger,没有社交技巧,所以我很遗憾地问我的上一个(?)问题(因为这些系统只针对没有障碍的人制作)。
我正在使用GCD从Instagram加载图片和视频。我在一个非常繁忙的应用程序中执行此操作。凭借其用户界面,我希望保持平稳运行,因此我在后台加载Instagram媒体。
下面的代码(我可能以错误的方式格式化,所以我在前面道歉)工作正常,并且确实想要我想要它。它在后台加载图像(我离开了视频以保持简单),我的主UI是图像加载时的响应。我在负载之间显示它们,也可以正常工作。
然而
10分钟后,有时20分钟,有时30分钟甚至有时两小时后我的应用程序获得OSSpinLockLock冻结。如果我删除下面的代码,我没有媒体,但应用程序永远不会冻结。
我已经在网上搜索了关于其他方法来完成这项工作并找到OSSpinLockLock的解释。没运气。我发现只有使用GCD不能导致OSSpinLockLock。我已经使用了我所有的仪器知识(我必须承认它比我想象的更有限),但我找不到错误。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_async(queue, ^(void) {
[[InstagramEngine sharedEngine] getMediaAtLocation:location count:kInstagramLocationBufferSize maxId:nil withSuccess:^(NSArray* media, InstagramPaginationInfo* paginationInfo) {
if (media && media.count>0) {
for (InstagramMedia* mediaObject in media) {
NSData* data = [[NSData alloc] initWithContentsOfURL:mediaObject.standardResolutionImageURL];
if (data) {
UIImage* img = [UIImage imageWithData:data];
if (img)
[self.locationBuffer addObject:img];
data = nil;
}
}
}
} failure:^(NSError *error) {
;
}];
});
如果您查看此代码,您是否看到任何可能导致该锁定的内容?因为我当然不会。
self.locationBuffer在.h中声明为
@property (nonatomic,strong) NSMutableArray* locationBuffer;
并且已正确分配和初始化(否则会更清楚问题是什么)。我也尝试过不把UIImage放在数组中,而是将NSData放在数组中但是没有任何区别。
在我的iPad迷你视网膜上,例如CPU负载达到195%并且在很长一段时间内保持在该数字附近。最终,有时几个小时后,应用程序崩溃了。
非常欢迎任何建议。
编辑:正如我现在看到的iPad本身的ips文件(由于一些神秘的原因,我无法粘贴到这个网页(堆栈溢出还处于试验阶段吗?))我看到iPad确实花费了16.000+ NSURLConnection上的秒数...
答案 0 :(得分:0)
我认为有些超时或失败会阻塞你的gcd队列太多时间。尝试使用NSOperationQueue
重写该代码,这样就可以在错误或视图/控制器消失时停止队列。
更新1:
这是我的代码试用,我添加了队列和日志,检查它们并检查超时值。这样,如果请求未完成(最有可能),您可以跟踪它。所有请求都是连续的,因此如果其中一个请求停止,您应立即注意到它。 您可以创建多个队列并按顺序访问它们(循环)以同时获得更多请求。我不会使用超过4个队列,这也是大多数桌面互联网浏览器的默认值。
// keep the same queue for all request (class member?), don't put it in the same block
NSOperationQueue* queue= [[NSOperationQueue alloc] init];
// keep this in another code block from queue
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul), ^(void) {
[[InstagramEngine sharedEngine] getMediaAtLocation:location count:kInstagramLocationBufferSize maxId:nil withSuccess:^(NSArray* media, InstagramPaginationInfo* paginationInfo) {
if (media && media.count>0) {
for (InstagramMedia* mediaObject in media) {
NSURL* url= mediaObject.standardResolutionImageURL;
NSLog(@"Start loading from %@", url);
NSURLRequest* req= [NSURLRequest requestWithURL:mediaObject.standardResolutionImageURL
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:30]; // 30 seconds timeout
[NSURLConnection sendAsynchronousRequest:req queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSLog(@"Stop loading from %@ %@ %@", url, response, connectionError);
if (data != nil && connectionError == nil) {
UIImage* img = [UIImage imageWithData:data];
if (img) {
// if you are triggering some ui update run on main thread
// [self.locationBuffer addObject:img];
[self.locationBuffer performSelectorOnMainThread:@selector(addObject:)
withObject:img
waitUntilDone:NO];
}
}
}];
}
}
} failure:^(NSError *error) {
NSLog(@"Error getting media list: %@", error);
}];
});
答案 1 :(得分:0)
OSSpinLocks在iOS8.3 +上有错误:report
这导致了这种冻结
我认为你应该用其他东西替换OSSpinLocks来修复你的应用程序(也许创建你自己的自旋锁实现 - 搜索OS for OSSpinLock)。