以下代码下载图像并使用块返回结果,以便我可以利用块和Grand Central Dispatch的异步功能.我发现如果图像或错误对象为零,我会收到EXC_BAD_ACCESS错误.如果参数的值为零,它总是会导致错误吗?
失败的部分是returnImage块,用于在方法结束时返回图像.
- (void)downloadImageWithBlock:(void (^)(UIImage *image, NSError *error))returnImage {
dispatch_queue_t callerQueue = dispatch_get_current_queue();
dispatch_queue_t downloadQueue = dispatch_queue_create("Image Downloader Queue", NULL);
dispatch_async(downloadQueue, ^{
UIImage *image = nil;
NSError *error;
// get the UIImage using imageURL (ivar)
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Downloading: %@", imageURL);
});
NSURL *url = [NSURL URLWithString:imageURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSURLResponse *urlResponse = nil;
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&error];
if (!error && response) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Success!");
});
image = [UIImage imageWithData:response];
}
// image …Run Code Online (Sandbox Code Playgroud) 我正在使用iOS 5开发iOS应用程序.
我无法使用宏中央调度来填充GMGridViewCell的视图.
问题不在于GridCell本身,而是在GCD中访问数据.
这是我的代码:
- (GMGridViewCell *)GMGridView:(GMGridView *)gridView cellForItemAtIndex:(NSInteger)index
{
//NSLog(@"Creating view indx %d", index);
CGSize size = [self sizeForItemsInGMGridView:gridView];
GMGridViewCell *cell = [gridView dequeueReusableCell];
if (!cell)
{
cell = [[GMGridViewCell alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
}
[[cell.contentView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
dispatch_queue_t fillCellQueue = dispatch_queue_create("Cell fetch queue", NULL);
dispatch_async(fillCellQueue, ^{
SearchGridViewCell *cellView = [UIView loadFromNib:@"SearchGridViewCell" owner:self];
Item *item = [self.foundItems objectAtIndex:index];
cellView.itemImageView.image = [UIImage imageWithData:item.image.thumb];
cellView.itemNameLabel.text = item.name;
cellView.brandImageView.image = [UIImage imageWithData:item.group3.image.thumb];
Attribute *itemAttribute = [item.attributes objectAtIndex:0];
cellView.attributeLabel.text = [itemAttribute.name …Run Code Online (Sandbox Code Playgroud) 当我创建单元格时,我正在进行一些繁重的计算.我试图弄清楚保持UITableView流体的最佳方法,但是在同一类型上进行背景计算(保持UI线程没有太多处理).
仅出于测试目的,我将此作为我的重计算方法:
+(NSString*)bigCalculation
{
int finalValue=0;
int j=0;
int i=0;
for (i=0; i<1000; i++) {
for (j=0; j<10000000; j++) {
j++;
}
finalValue+=j/100*i;
}
return [NSString stringWithFormat:@"%d",finalValue];
}
Run Code Online (Sandbox Code Playgroud)
在cellForRowAtIndexPath中,我只做以下事情:
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier=@"identifier";
UITableViewCell *cell=nil;
cell=[aTableView dequeueReusableCellWithIdentifier:identifier];
if(!cell)
{
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
}
NSString *text=[dataSource objectForKey:[[dataSource allKeys] objectAtIndex:indexPath.row]];
dispatch_queue_t a_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
;
dispatch_async(a_queue, ^{
NSString *subtitle=[CalculationEngine bigCalculation];
dispatch_async(dispatch_get_main_queue(), ^{
[[cell detailTextLabel] setText:subtitle];
dispatch_release(a_queue);
});
});
[[cell textLabel] setText:text];
return cell;
}
Run Code Online (Sandbox Code Playgroud)
目前我有UITableView流体,而在后台一切正常.所以我的问题是: …
iphone concurrency multithreading grand-central-dispatch ios
如果我有两个不同的线程通过GCD访问一个NSMutableArray而一个只是创建一个基于可变数组的新数组而另一个线程正在从数组中删除记录,我应该期望这是一个问题吗?也就是说,我认为副本不应该只是"读取"数组,只是得到当时阵列中发生的一切?我没有在任何一个线程中枚举数组,但它仍然崩溃.一旦我删除了读取例程,它就可以正常工作.
这是"阅读":
dispatch_async(saveQueue, ^{
NSDictionary*tempstocks=[NSDictionary dictionaryWithDictionary:self.data];
Run Code Online (Sandbox Code Playgroud)
它崩溃在这个线程上: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[9]'
以下是另一个线程上发生的事情:
[self.data removeObjectForKey:item];
Run Code Online (Sandbox Code Playgroud)
我知道你在枚举的时候不能变异,但我认为在变异时读取是可以的,你可能不知道你得到了哪个版本的变异对象,但我不认为这是一个问题,但显然它是.也许该dictionaryWithDictionary方法正在执行首先看到X对象的操作,但是在例程完成时它包含XY对象,因此它self.data在运行时不会在一次捕捉中"捕获"整个字典,dictionaryWithDictionary而是枚举self.data哪个基本上是与枚举时的突变问题相同?
我在iPad上有一个功能,我需要按顺序运行3个步骤,比如task1,task2,task3.Task2需要从服务器加载一些数据.所以我需要将task2放入一个单独的后台线程中.
- (IBAction)dbSizeButton:(id)sender {
//Task1......
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
//Task2 .....which go to server and download some stuff and update database.
dispatch_sync(dispatch_get_main_queue(), ^{
//Task3, continue to work on UI
});
});
}
Run Code Online (Sandbox Code Playgroud)
但看起来正在发生的事情是当Task2启动时应用程序经常被杀死.我不确定为什么.我可以看到Task2确实在一个单独的线程中执行.所以我想知道,如果不是这样做的方式,而不是使用GCD,我可以在Task2的末尾向主线程发送消息或通知,以便我可以启动Task3吗?怎么做到这一点?
我想在一些条件检查后处理一些代码.首先是一些变量必须是true(我有一个Key-Value Observer分配给它).第二 - 如果该变量尚未变为true一段时间(例如5秒),则永远不要处理变量并只处理代码.
我带来了一个明显的解决方案,我认为这个解决方案很糟糕:while()每次检查true条件和时间都会在另一个调度队列中进行无限循环.所有这些代码都包含在另一个调度队列中......好吧,对我来说并不好看.
我想做的伪代码草案:
WHEN (5 seconds are gone || getCurrentDynamicExpr() == true) {
processStuff();
}
Run Code Online (Sandbox Code Playgroud)
什么是正确而简单的方法呢?
编辑
这里看起来很混乱......要更具体一点:
我想,当它集中捕捉镜头,所以我要检查AVCaptureDevice的isAdjustingFocus属性(我使用AVCaptureStillImageOutput),然后捕获了一枪.5秒钟是..好吧,如果它没有聚焦,那么出现问题,所以无论如何都要拍照.
我很抱歉混淆,认为这是非常普遍的事情..
当我只在主线程上执行以下操作时iref立即自动释放:
-(void)loadImage:(ALAsset*)asset{
@autoreleasepool {
ALAssetRepresentation* rep = [asset defaultRepresentation];
CGImageRef iref = [rep fullScreenImage];
UIImage* image = [UIImage imageWithCGImage:iref
scale:[rep scale]
orientation:UIImageOrientationUp];
[self.imageView setImage:image];
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我执行imageWithCGImage时:在后台线程上使用GCD iref不会像第一个例子那样立即释放.大约一分钟后:
-(void)loadImage:(ALAsset*)asset{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
@autoreleasepool {
ALAssetRepresentation* rep = [asset defaultRepresentation];
CGImageRef iref = [rep fullScreenImage];
UIImage* image = [UIImage imageWithCGImage:iref
scale:[rep scale]
orientation:UIImageOrientationUp];
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self.imageView setImage:image];
});
}
});
}
Run Code Online (Sandbox Code Playgroud)
如何CGImageRef立即释放对象?
之前的研究:
CGImageRef物体已被分配,并且在它应该被释放后仍然存活了大约一分钟.CGImageRef对象,CGImageRelease我会在图像尝试自动释放一分钟后获得BAD_EXEC异常.iref …我正在开发一个应用程序,当它开始执行时,它必须从webService获取一些数据,类别,加载图像(有时会更改),信息"如何使用"(也可以在服务器中更改,客户端规范.. ).为了获得这些数据,我调用了一些像这样的方法(我有四个类似的方法,每个我需要的一个方法):
-(void) loadAppInfo
{
__weak typeof(self) weakSelf = self;
completionBlock = ^(BOOL error, NSError* aError) {
if (error) {
// Lo que sea si falla..
}
[weakSelf.view hideToastActivity];
};
[self.view makeToastActivity];
[wpNetManager getApplicationInfoWithCompletionBlock:completionBlock];
}
Run Code Online (Sandbox Code Playgroud)
在我的网络管理器中,我有类似这样的方法:
- (void)getApplicationInfoWithCompletionBlock:(CompletionBlock)completionBlock
{
NSString * lang = @"es";//[[NSLocale preferredLanguages] objectAtIndex:0];
NSString *urlWithString = [kAPIInfoScreens stringByAppendingString:lang];
NSMutableURLRequest *request = nil;
request = [self requestWithMethod:@"GET" path:urlWithString parameters:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[self registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// Print the response …Run Code Online (Sandbox Code Playgroud) objective-c nsoperationqueue grand-central-dispatch ios objective-c-blocks
我想知道这两者之间的性能差异.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
// perform complex operation
// dispatch back to main thread to update UI
});
dispatch_async(_myCustomConcurrentQueue, ^{
// perform complex operation
// dispatch back to main thread to update UI
});
Run Code Online (Sandbox Code Playgroud)
我的假设是在整个操作系统和其他应用程序中使用GCD,它需要执行非常快速的后台任务,并且快速完成.创建的自定义队列与GCD是分开的,它们可以运行不同的任务,并在释放后添加回池中.所以我的假设是我的customQueue比复杂操作的GCD表现更好.
你的想法是什么?哪个表现更好?它们是一样的吗?
multithreading cocoa-touch objective-c grand-central-dispatch ios
dispatch_benchmark()是一个GCD不导出的函数.但是,您可以Objective C通过在代码中声明它来调用它:
uint64_t dispatch_benchmark(size_t count, void (^block)(void));
Run Code Online (Sandbox Code Playgroud)
我怎么能这样做Swift?
ios ×6
objective-c ×5
cocoa ×2
concurrency ×2
iphone ×2
c ×1
cocoa-touch ×1
core-data ×1
memory ×1
swift ×1
xcode ×1