我有一项需要每1秒执行一次的任务.目前我每隔1秒就有一次NSTimer重复射击.如何在后台线程(非UI线程)中触发计时器?
我可以在主线程上使用NSTimer激发然后使用NSBlockOperation来调度后台线程,但我想知道是否有更有效的方法来执行此操作.
我有一个应用程序,目前NSURLConnection
用于其绝大多数网络.我想搬到,NSURLSession
因为Apple告诉我这是要走的路.
我的应用只是NSURLConnection
通过+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error
类方法使用同步版本.我在NSBlockOperation
运行中执行此操作,NSOperationQueue
因此我不会不必要地阻止主队列.以这种方式做事的最大好处是我可以使操作彼此依赖.例如,我可以让请求数据的任务依赖于登录任务完成.
我没有看到任何对同步操作的支持NSURLSession
.所有我能找到的文章都是嘲笑我甚至想要同步使用它而且我是一个阻止线程的可怕人物.精细.但我认为没有办法让NSURLSessionTask
彼此依赖.有没有办法做到这一点?
或者有描述我将如何以不同的方式做这样的事情?
我是块的忠实粉丝,但没有将它们用于并发.经过一些谷歌搜索,我拼凑了这个想法,以隐藏我在一个地方学到的一切.目标是在后台执行一个块,当它完成时,执行另一个块(如UIView动画)......
- (NSOperation *)executeBlock:(void (^)(void))block completion:(void (^)(BOOL finished))completion {
NSOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:block];
NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
completion(blockOperation.isFinished);
}];
[completionOperation addDependency:blockOperation];
[[NSOperationQueue mainQueue] addOperation:completionOperation];
NSOperationQueue *backgroundOperationQueue = [[NSOperationQueue alloc] init];
[backgroundOperationQueue addOperation:blockOperation];
return blockOperation;
}
- (void)testIt {
NSMutableString *string = [NSMutableString stringWithString:@"tea"];
NSString *otherString = @"for";
NSOperation *operation = [self executeBlock:^{
NSString *yetAnother = @"two";
[string appendFormat:@" %@ %@", otherString, yetAnother];
} completion:^(BOOL finished) {
// this logs "tea for two"
NSLog(@"%@", string);
}];
NSLog(@"keep this operation …
Run Code Online (Sandbox Code Playgroud) objective-c nsoperation nsoperationqueue ios nsblockoperation
我必须定义应该以一定的时间间隔定期调用的方法.我需要在另一个线程(非主线程)中调用它,因为此方法用于从外部API获取信息并在核心数据中同步数据.
如何定义此方法以阻止主线程?
我必须从RestAPI中同步一堆信息.我必须做6次RestAPI调用才能完成工作.我用Blocks设计了API调用,如果有的话,返回NSError.这些调用中的3个应该执行嵌套,因为第一个调用向其他调用提供信息并允许执行,而其他3个调用可以独立运行.由于提高了网络性能,我将同步调用设计如下:
最后一个NSBlockOperation依赖于前两个NSBlockOperation.
我还有一个NSOperationQueue,它包含所有三个NSBlockOperation,其中信号量NSBlockOperation作为队列中的最后一个添加.我要实现的结果是:前两个块名为Concurrently,当它们的工作完成时,调用信号量NSBlockOperation并将控件返回给提供UIAlertMessage的用户.
结果不是之前解释的:返回控件而不等待syncAllBlocksInformation块的结束.
在包含NSBlockOperation的代码下面:
-(void)syncAllBlocksInformation:(void(^)(NSError *error))completion{
__block NSError *blockError = nil;
NSOperation *syncUserInfoOperation = [NSBlockOperation blockOperationWithBlock:^{
[dataSync syncUserInfo:tfMail.text password:tfPassword.text completion:^(NSError *error, NSNumber *idUser) {
if(!error){
[dataSync syncUserfilesInfo:idUser completion:^(NSError *error) {
if(!error){
[dataSync syncUserBookings:^(NSError *error) {
if(error){
blockError = error;
}
}];
}
else{
blockError = error;
}
}];
}
else{
blockError = error;
}
}];
}];
NSBlockOperation *otherSyncOperations = [NSBlockOperation blockOperationWithBlock:^{
[dataSync syncNewsInfo:^(NSError *error) {
if(error){
blockError = error;
NSLog(@"error %@",error);
}
}]; …
Run Code Online (Sandbox Code Playgroud) objective-c nsoperationqueue ios objective-c-blocks nsblockoperation
我是嵌套块,它看起来像UGGGGLY.有没有办法写这个不那么难看?主要是寻找语法建议,而不是结构,但我也会接受.
我的块工厂方法,
-(NSImage *(^)(CGFloat size, BOOL preview))resizeBlock {
return (NSImage *(^)(CGFloat size, BOOL preview))[[^(CGFloat size, BOOL preview){
// image-resizing code
return [[[NSImage alloc] init] autorelease];
} copy] autorelease];
}
Run Code Online (Sandbox Code Playgroud)
从许多类似于此的函数调用
-(void)queueResize:(CGFloat)targetSize toView:(NSImageView *)targetView {
NSImage*(^sizeBlock)(CGFloat,BOOL) = [self resizeBlock];
NSBlockOperation *bo = [NSBlockOperation blockOperationWithBlock:^(void) {
NSImage *previewImage = (NSImage*)sizeBlock(targetSize,YES);
targetView.image = previewImage;
}];
[queue addOperation:bo];
}
Run Code Online (Sandbox Code Playgroud)
queue是一个NSOperationQueue对象.没有所有(丑陋的丑陋)演员,它将无法编译.Amidoinitrite?
编辑:根据Dave DeLong的回答,和http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/,我改变了行
targetView.image = previewImage;
Run Code Online (Sandbox Code Playgroud)
成为,
[targetView performSelectorOnMainThread:@selector(setImage:) withObject:previewImage waitUntilDone:YES];
Run Code Online (Sandbox Code Playgroud) 注意:
这只是一个概念验证。
真正的后台任务是不断请求原始数据的“HTTP Get”并通过主线程显示;一经请求。
场景:
1)按需切换后台任务(循环)。
2) 后台任务在每次迭代时通知主线程 UI。
3) 只有一 (1) 个块操作在队列中运行。
Modus Operandus
1) 使用 NSBlockOperation 来包含后台代码。
2)使用区域BOOL来切换循环;通过 IBAction。
问题
1) 编译器将 BOOL 'isRunning' 标记为强链接:
在此块中强烈捕获“自我”可能会导致保留循环。
2)在尝试添加块操作之前,我检查了队列中是否有任何操作。
但我总是收到以下错误:
-[NSOperationQueue addOperation:]: 操作完成,不能入队
除了上述问题之外,这种概念验证似乎正在发挥作用。
问题:
1) 为什么编译将 BOOL 'running' 标记为一个强行,而它只是一个缩放器?
2)如果在队列中没有找到,为什么我不能通过添加另一个 NSBlockOperation 来重用 NSOperationQueue?
以下是整个代码:
#define START 0
#define STOP 1
@interface ricViewController ()
@property (assign) BOOL running;
@end
@implementation ricViewController {
NSOperationQueue *operationQueue;
NSBlockOperation *blockOperation;
void (^backgroundBlock)(void);
}
@synthesize running = isRunning;
#pragma mark - ViewController methods …
Run Code Online (Sandbox Code Playgroud) 我问这个问题关于我的问题以有效的方式显示photolibrary图像iPhone和高效的UITableView"cellForRowIndexPath"方法来绑定PhotoLibrary图像.
所以我想请求答案不重复到这个没有阅读以下细节:)
我们来讨论这个问题,
我已经详细研究了上面提到的问题,我从这里找到了关于操作队列的文档.
所以我创建了一个示例应用程序,通过ALAsset块使用操作队列显示七个照片库图像.
以下是示例应用程序详细信息.
步骤1:
在NSOperationalQueueViewController viewDidLoad方法中,我已将所有照片库ALAsset URL检索到名为的数组中urlArray
.
第2步:
将所有URL添加到之后urlArray
, if(group!= nil)条件将为false assetGroupEnumerator
,因此我创建了一个NSOperationQueue
,然后通过for
循环创建了七个UIImageView 并NSOperation
使用相应的图像视图和URL创建了我的子类对象为每一个并将它们添加到NSOperationQueue
.
在这里查看我的NSOperation
子类.
在这里查看我的实现(VierwController)类.
我们来讨论这个问题吧.
它不会始终显示所有七个图像.一些图像丢失了.丢失的顺序多次改变(一次不显示第六和第七次,另一次不显示第二次和第三次).控制台日志显示无法找到照片图片编号.但是,URL已正确记录.
您可以在此处查看日志详细信息.
我班上有错吗?
另外,当我浏览上面提到的操作队列文档时,我已经阅读过了NSBlockOperation
.我是否需要实现NSBlockOperation
而不是NSOperation
在处理ALAsset块时?
该NSBlockOperation
说明称
您原样使用的类是同时执行一个或多个块对象.因为它可以执行多个块,所以块操作对象使用组语义进行操作; 只有当所有关联的块都已完成执行时,操作本身才被认为已完成.
如何NSBlockOperation
针对我的示例应用程序实现with ALAsset块?
我已经完成了Stack …
iphone nsoperation nsoperationqueue nsblockoperation alassetslibrary
我在引用块本身内的 \xc2\xb4NSBlockOperation\xc2\xb4 时遇到麻烦。我需要检查操作是否被取消,并且似乎在启用 ARC 的项目中运行时,对 \xc2\xb4searchOperation\xc2\xb4 的任何访问都会泄漏。
\n\n这段代码基本上什么也不做,在启用 ARC 的项目中显示了泄漏,而在非 ARC 项目中则工作正常。
\n\n- (void)viewDidLoad\n{\n [super viewDidLoad];\n\n self.searchQueue = [[NSOperationQueue alloc] init];\n self.searchQueue.maxConcurrentOperationCount = 1;\n\n __block NSBlockOperation *searchOperation = [NSBlockOperation blockOperationWithBlock:^{\n if (searchOperation.isCancelled) return;\n }];\n\n [self.searchQueue addOperation:searchOperation];\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n谢谢。
\nobjective-c ×8
ios ×5
iphone ×2
nsoperation ×2
nsrunloop ×2
nstimer ×2
cloudkit ×1
cocoa ×1
nsurlsession ×1