例如,我有100次for循环.并且需要更新UIImageView,最后2个方法慢慢相同.为什么?他们之间有什么不同?
//fastest
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[btnThumb setImage:[UIImage imageWithData:data] forState:UIControlStateNormal];
[scrollView addSubview:btnThumb];
}];
//slowly
dispatch_async(dispatch_get_main_queue(), ^
{
[btnThumb setImage:[UIImage imageWithData:data] forState:UIControlStateNormal];
[scrollView addSubview:btnThumb];
});
//slowly
[btnThumb setImage:[UIImage imageWithData:data] forState:UIControlStateNormal];
[self performSelectorOnMainThread:@selector(testMethod:) withObject:[NSArray arrayWithObjects:scrollView, btnThumb, nil] waitUntilDone:NO];
-(void) testMethod:(NSArray*)objs
{
UIScrollView *scroll = [objs objectAtIndex:0];
UIButton *btn = [objs lastObject];
[scroll addSubview:btn];
}
Run Code Online (Sandbox Code Playgroud) 也就是说,如果我们几次排队同样的事情就不会有并发性.我们首先排队的那个将首先被执行.
我的意思是只有一个主线程对吗?
我们有一个关于 NSOperationQueue 的简单问题,这是一个简单的操作逻辑:
self.queue = [[NSOperationQueue alloc] init];
NSOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"- Running operation A");
[NSThread sleepForTimeInterval:1.2];
NSLog(@"- Done operation A");
}];
NSOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"- Running operation B");
[NSThread sleepForTimeInterval:2];
NSLog(@"- Done operation B");
}];
[operationA setCompletionBlock:^{
NSLog(@"-- Completion Block A");
}];
[operationB setCompletionBlock:^{
NSLog(@"-- Completion Block B");
}];
[operationB addDependency:operationA];
[self.queue addOperations:@[operationA, operationB] waitUntilFinished:NO];
Run Code Online (Sandbox Code Playgroud)
这是最终的输出
2015-12-21 14:59:57.463 SampleProject[18046:310901] - Running operation A
2015-12-21 14:59:58.664 SampleProject[18046:310901] - Done operation A
2015-12-21 14:59:58.664 SampleProject[18046:310900] - Running …Run Code Online (Sandbox Code Playgroud) 当执行彼此依赖的操作时,OperationQueue可以使用它们来确保它们以正确的顺序执行.但是,是否也可以确保操作一个接一个地完成?
让我们假设一个异步执行的方法,需要一些时间才能完成:
public func performOperation(_ number: Int, success: @escaping (Int) -> Void)->Void {
DispatchQueue(label: "operations").async {
print("Operation #\(number) starts")
usleep(useconds_t(1000-number*200)) // Block thread for some time
success(number)
}
}
Run Code Online (Sandbox Code Playgroud)
操作和依赖关系创建如下:
let operationQueue = OperationQueue.main
for operationNumber in 0..<4 { // Create operations as an example
let operation = BlockOperation(block: {
performOperation(operationNumber) { number in
DispatchQueue.main.sync {
print("Operation #\(number) finished")
}
}
})
operation.name = "Operation #\(operationNumber)"
if operationNumber > 0 {
operation.addDependency(operationQueue.operations.last!)
// Print dependencies
print("\(operation.name!) should finish …Run Code Online (Sandbox Code Playgroud) 问题很简单:我的应用程序控制每次启动时是否有更新.如果有更新,弹出窗口将显示是或否选择.当用户点击是4方法开始.这些方法下载xml文件并上传CoreData.这是警报的代码:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex==1) {
[self showActivityViewer];
[self downloadControlAndUpdatePoi];
[self downloadControlAndUpdateItinerari];
[self downloadControlAndUpdateArtisti];
[self downloadControlAndUpdateEventi];
[self hideActivityViewer];
NSLog(@"AGGIORNA");
} else {
NSLog(@"NON AGGIORNARE");
return;
}
}
Run Code Online (Sandbox Code Playgroud)
但是有一个问题:当用户点击是时,警报不会消失并保留在屏幕上,直到所有方法都完成.所以我尝试这个其他代码:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex==1) {
[self showActivityViewer];
[NSThread detachNewThreadSelector:@selector(startDownloads) toTarget:self withObject:nil];
[self hideActivityViewer];
NSLog(@"AGGIORNA");
} else {
NSLog(@"NON AGGIORNARE");
return;
}
}
-(void)startDownloads {
NSInvocationOperation *opPoi=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdatePoi) object:nil];
NSInvocationOperation *opItinerari=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdateItinerari) object:nil];
NSInvocationOperation *opArtisti=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdateArtisti) object:nil];
NSInvocationOperation *opEventi=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdateEventi) object:nil]; …Run Code Online (Sandbox Code Playgroud) 我有一个NSFetchedResultsController主线程.同样从主线程,我异步发送JSON的网络请求.当JSON字符串返回时,我启动NSOperation一个新的(后台)NSManagedObjectContext,解析JSON字符串,创建/更新NSManagedObject,并将它们保存在上下文中.后台上下文与主上下文具有相同的persistentStore.有了这个,我有两个问题:
我认为从任何上下文(在任何线程上)对持久性存储的任何保存都会通知主要NSFetchedResultsController有变化,但到目前为止它没有发现任何变化.我应该做些什么来通知主线程NSFetchedResultsController有外部save的,以便相应的tableView更新?
因此,在主线程上,我订阅NSManagedObjectContextWillSaveNotification并正确查看所有上下文(包括完全在单独线程上存在的上下文)何时执行save操作.的苹果文档说的是notification.userInfo具有应3个阵列,一个阵列的每个在后台线程的"更新,删除和插入的"模型对象的字典.但是,这对我userInfo来说总是如此nil.我有什么想法我做错了吗?
订阅NSManagedObjectContextWillSaveNotificationAppDelegate:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(managedObjectContextDidSave:)
name:NSManagedObjectContextWillSaveNotification
object:nil];
Run Code Online (Sandbox Code Playgroud)
以及在AppDelegate中保存上下文的方法:
- (void)managedObjectContextDidSave:(NSNotification *)notification {
DLog(@"notification: %@", notification); //not nil
DLog(@"notification user info: %@", notification.userInfo); // always nil... why??
NSManagedObjectContext *theContext = notification.object;
if(theContext != context) {
DLog(@"---- SAVED ON ANOTHER CONTEXT");
// should I notify NSFetchedResultsController that there were …Run Code Online (Sandbox Code Playgroud) multithreading core-data nsfetchedresultscontroller nsoperationqueue nsmanagedobjectcontext
我正在使用AFNetworking Framework来帮助将照片上传到网站.上传工作正常,但我需要在UIProgressView中显示进度.问题是,在上传开始后,进度从0到100%左右移动,并且在一段时间内保持100%,具体取决于上传的照片数量.我使用一个请求一次上传1到6张照片.关于这里发生了什么的任何想法?AFNetworking不包括照片的大小吗?
它在NSLOG中正确显示:
2012-04-03 10:49:45.498 PhotoUp[3689:2207] Sent 32768 of 217931 bytes
2012-04-03 10:49:45.499 PhotoUp[3689:2207] Sent 65536 of 217931 bytes
2012-04-03 10:49:45.501 PhotoUp[3689:2207] Sent 98304 of 217931 bytes
2012-04-03 10:49:45.502 PhotoUp[3689:2207] Sent 131072 of 217931 bytes
2012-04-03 10:49:47.795 PhotoUp[3689:2207] Sent 134310 of 217931 bytes
2012-04-03 10:49:49.070 PhotoUp[3689:2207] Sent 136730 of 217931 bytes
2012-04-03 10:49:50.819 PhotoUp[3689:2207] Sent 139150 of 217931 bytes
2012-04-03 10:49:52.284 PhotoUp[3689:2207] Sent 141570 of 217931 bytes
Run Code Online (Sandbox Code Playgroud)
这是代码:
NSString *numberOfPhotosAsString = [NSString stringWithFormat:@"%d", numberOfPhotos];
NSString *fileBase = @"file0_";
NSString *fileNameBase …Run Code Online (Sandbox Code Playgroud) nsoperation uiprogressview nsoperationqueue ios afnetworking
这是一个两部分问题.希望有人可以回答完整的答案.
NSOperations是强大的对象.它们可以是两种不同的类型:非并发或并发.
第一种类型同步运行.您可以通过将非并发操作添加到a中来利用它们NSOperationQueue.后者为您创建一个线程.结果包括以并发方式运行该操作.唯一需要注意的是这种操作的生命周期.当其main方法完成时,它将从队列中删除.处理异步API时,这可能是一个问题.
现在,并发操作呢?来自Apple doc
如果要实现并发操作(即,相对于调用线程异步运行的操作),则必须编写其他代码以异步启动操作.例如,您可能会生成一个单独的线程,调用异步系统函数或执行任何其他操作以确保start方法启动任务并立即返回,并且很可能在任务完成之前返回.
这对我来说几乎是清楚的.它们以异步方式运行.但是你必须采取适当的行动来确保他们这样做.
我不清楚的是以下内容.Doc说:
注意:在OS X v10.6中,操作队列忽略isConcurrent返回的值,并始终从单独的线程调用操作的start方法.
它的真正含义是什么?如果我在一个并发操作中会发生NSOperationQueue什么?
然后,在此并发操作中,并发操作用于通过NSURLConnection(以其异步形式)下载某些HTTP内容.操作是并发的并包含在特定队列中.
UrlDownloaderOperation * operation = [UrlDownloaderOperation urlDownloaderWithUrlString:url];
[_queue addOperation:operation];
Run Code Online (Sandbox Code Playgroud)
由于NSURLConnection需要循环运行,作者start在主线程中分流方法(所以我想将操作添加到它产生不同的队列的队列中).以这种方式,主运行循环可以调用操作中包含的委托.
- (void)start
{
if (![NSThread isMainThread])
{
[self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO];
return;
}
[self willChangeValueForKey:@"isExecuting"];
_isExecuting = YES;
[self didChangeValueForKey:@"isExecuting"];
NSURLRequest * request = [NSURLRequest requestWithURL:_url];
_connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self];
if (_connection == nil)
[self finish];
}
- (BOOL)isConcurrent
{ …Run Code Online (Sandbox Code Playgroud) 是否可以安全地添加NSOperationQueue到一个NSOperation,然后将此操作添加到另一个NSOperationQueue?
这里有一些代码可视化我想要做的事情.
NSOperationQueue *mainQueue = [NSOperationQueue alloc] init];
// Here I declare some NSBlockOperation's, i.e. parseOperation1-2-3
// and also another operation called zipOperation, which includes
// an NSOperationQueue itself. This queue takes the processed (parsed) files
// and write them to a single zip file. Each operation's job is to write the data
// stream and add it to the zip file. After all operations are done,
// it closes the zip.
[zipOperation addDependency:parseOperation1]; …Run Code Online (Sandbox Code Playgroud) 在此先感谢您的帮助,我有两个API调用,两个都是并发的,任何调用都可以先成功(我不想按顺序调用),两个调用成功后,我必须停止我的活动指示器并重新加载我的tableView ,这是我的代码,但我不知道这是否正确以及如何重新加载我的tableView并停止我的活动指示器.
func downloadDetails(){
let operationQueue: OperationQueue = OperationQueue()
let operation1 = BlockOperation() {
WebServiceManager.getAData(format:A, withCompletion: {(data: Any? , error: Error?) -> Void in
if let success = data {
DispatchQueue.main.async {
(success code)
}
}
})
let operation2 = BlockOperation() {
webServiceManager.getBData(format: B, withCompletion: {(data: Any? , error: Error?) -> Void in
if let success = data {
DispatchQueue.main.async {
(success code)
}
}
})
}
operationQueue.addOperation(operation2)
}
operationQueue.addOperation(operation1)
}
downloadDetails() "calling function"
Run Code Online (Sandbox Code Playgroud) nsoperationqueue ×10
ios ×7
nsoperation ×7
objective-c ×4
afnetworking ×1
asynchronous ×1
background ×1
concurrency ×1
core-data ×1
nsthread ×1
swift ×1
swift4 ×1
swift4.1 ×1
xcode4.5 ×1