通过快速枚举来枚举是否安全[NSOperationQueue operations]?像这样:
for (NSOperation *op in [operationQueue operations]) {
// Do something with op
}
Run Code Online (Sandbox Code Playgroud)
由于操作是异步的并且在另一个线程上执行,operations因此可以随时更改(包括在主线程执行期间).快速枚举是否可以防止这种情况,或者我应该copy(和autorelease)操作数组?
cocoa cocoa-touch nsoperation fast-enumeration nsoperationqueue
我已经实现了以下NSOperation,以绘制N自定义视图
- (void)main {
for (int i=0; i<N; i++) {
<< Alloc and configure customView #i >>
//(customView is a UIView with some drawing code in drawrect)
[delegate.view addSubview:customView];
}
NSLog(@"Operation completed");
}
Run Code Online (Sandbox Code Playgroud)
在我的customView的drawRect方法中
- (void)drawRect {
<<Drawing code>>
NSLog(@"Drawed");
delegate.drawedViews++;
if (delegate.drawedViews==VIEWS_NUMBER) {
[delegate allViewsDrawn];
}
}
Run Code Online (Sandbox Code Playgroud)
因此,代表在绘制所有视图时获取通知.
问题是在"操作完成"日志之后,我需要大约5秒才能看到第一个"绘制"日志.
为什么会这样?一般来说,我应该如何表现出哪一行代码占用了这么多时间呢?
------编辑------
有时候(就像10次中的1次一样)我正在崩溃这样做,因为我不应该addsubview从NSOperation 调用,因为它不是线程安全的.所以我改为
[delegate.view performSelectorOnMainThread:@selector(addSubview:) withObject:customView waitUntilDone:NO];
Run Code Online (Sandbox Code Playgroud)
现在我不再崩溃,但这个过程需要很长时间才能执行!比以前多5倍.
为什么这么慢?
我正在使用NSOPerationqueue开发应用程序.它显示我在队列中添加OperationBlock时泄漏,如下图所示.请帮我找出泄漏分辨率.如果您需要更多屏幕截图或细节请告诉我.
您还可以在图像中查看我的代码.



我有一堆NSOperations添加到了NSOperationQueue.操作队列maxConcurrentOperationCount设置为1,以便NSOperations一个接一个地运行.
现在,在completionBlock一个NSOperation我想取消所有未决NSOperations调用cancelAllOperations的NSOperationQueue.
这样做安全吗?我可以确定start只有completionBlock在前一个操作完全执行后才调用下一个操作的方法吗?或者执行completionBlock上一个操作和当前操作的任务同时运行?
我之所以要问:我使用AFNetworking来执行一批AFHTTPRequestOperations并且只有在批量的所有先前请求都成功时才执行一个请求.
NSOperationQueue创建了许多线程,正如您所期望的那样.但是当您暂停应用程序并在Xcode中调试它时,不清楚哪些线程属于一个操作队列,哪些线程属于另一个操作队列.
我试过了:
[NSThread currentThread] setName: @"My amazing operation thread"]
Run Code Online (Sandbox Code Playgroud)
但是当线程被重用时,这只意味着许多线程获得此名称,然后永远不会丢失它.我试过设置在线程名称-start和它解封-finish,但该线程的名字在Xcode调试线程列表从未露面.
命名线程/操作以使它们在Xcode中更容易调试的好方法是什么?
我正在处理的应用程序定期从应用程序服务器刷新它的本地数据缓存(10多个请求,每个请求需要相当长的时间).我目前正在异步运行这些请求,以至于不阻止UI线程.由于这些请求确实需要一段时间来处理然后加载到核心数据中,我想利用它的beginBackgroundTaskWithExpirationHandler依赖操作行为NSOperationQueue.
在我将所有请求添加到操作队列之后,我使用waitUntilAllOperationsAreFinishedto阻塞直到所有操作都完成(这不在主线程上).我在原型中看到的问题是,当我运行应用程序并立即背景(按下主页按钮)时,waitUntilAllOperationsAreFinished即使在所有操作完成后仍然会被阻止...但是一旦我再次打开应用程序,处理程序完成.如果我运行应用程序并让它保持在前台,一切都很好.在我的实际应用程序中,这种行为似乎并不总是发生,但是使用下面的示例代码,它似乎:
#import "ViewController.h"
@interface ViewController ()
@property (assign, nonatomic) UIBackgroundTaskIdentifier task;
@property (strong, nonatomic) NSOperationQueue *queue;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelectorInBackground:@selector(queueItUp) withObject:nil];
}
- (void)queueItUp {
UIApplication *application = [UIApplication sharedApplication];
self.queue = [[NSOperationQueue alloc] init];
self.task = [application beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"Took too long!");
[self.queue cancelAllOperations];
[application endBackgroundTask:self.task];
self.task = UIBackgroundTaskInvalid;
}];
for (int i = 0; i < 5; i++) {
[self.queue addOperationWithBlock:^{
[NSThread sleepForTimeInterval:3];
NSLog(@"Finished …Run Code Online (Sandbox Code Playgroud) 我有一个数据加载操作需要从主线程运行,以避免潜在的阻塞问题.为此,我使用了NSOperationQueue和NSOperations.
然而,出现的一个问题是存在一种操作以基于传入信息产生附加操作.试图解决这个问题也解决了我在其他地方遇到的一些小问题,因为我遇到的解决方案是给NSOperation它自己的子任务队列.
问题是,只要'main'退出,NSOperation将被标记为'finished',无论子队列是否已完成处理; 我该如何覆盖这种行为?
添加了下面调用方法的方法以及泄漏的对象是"allDBObjects"如果我删除它并将下面的字典更改为"NSMutableDictionary*objectsById",则没有泄漏.
几天后我没有回到这个问题上.我认为这完全取决于"解除分配问题"(https://developer.apple.com/library/ios/technotes/tn2109/_index.html#//apple_ref/doc/uid/DTS40010274-CH1-SUBSECTION11).我已经使用MKNetworkKit和AFNetworking 1.3.3进行了测试(更改1方法以使用AFNetworking而不是MKNetwork Kit),我仍然在完成块中泄漏这些对象.我在块中没有引用self并且使用AFNetworking我可以看到completionBlock设置为nil并且我试图通过设置[weakOp setCompletionBlock:nil]来手动中断保留周期.
编辑:下面的代码示例我尝试使用属性并将它们引用为weakSelf.我现在已将这些更改为局部变量,但它们仍然泄漏.
有任何想法吗?
我使用MKNetworkKit和Core Data接管了一个项目,在通过Leaks in instruments运行项目后,我可以在应用程序的不同位置看到很多泄漏的对象.
调试代码后,我可以看到泄漏的对象是在MKNetworkKit请求(setCompletionBlock :)的回调中发生的2次获取请求.需要完成提取请求以检查是否需要插入或更新数据.
一些进一步的信息 在完成块内部,我得到一个ManagedObjectContext的实例,并使用并发类型"NSPrivateQueueConcurrencyType"创建它,并执行插入我在moc上正确调用"performBlock:".
请指教.
詹姆士
块示例代码:请注意:我已经注释掉了2个获取请求,没有泄漏并将它们放回原因导致数百个对象泄漏,我设置NSDictionary和NSArray的weakSelf属性也是(非原子,强).
- (void) updateDbObjects: (int) page withCallback: (CompletionResultsNumberBlock) callback {
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
dispatch_queue_t callerQueue = dispatch_get_current_queue();
#pragma GCC diagnostic warning "-Wdeprecated-declarations"
__weak typeof(self) weakSelf = self;
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[self createFullPath:urlStr]]];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSManagedObjectContext *moc = [weakSelf managedObjectContextForCurrentThread];
DataRoot *dataRoot …Run Code Online (Sandbox Code Playgroud) memory-leaks objective-c nsoperationqueue ios objective-c-blocks
我想通过上传300张图片到服务器NSOperationQueue.我必须为每个图像使用一个URL,因此我将使用300个URL.换句话说NSOperation,这些网址需要300 秒NSOperationQueue.
这是正确的方法吗?它不会影响主线程中的应用程序性能吗?
我有一个NSOperationQueue,maxConcurrentOperationCount = 1,
和自定义NSOperation有一个属性是块,
当iOS 9.x中的NSOperationQueue addOperation,应用程序崩溃时,
NSOperation不是零.
以下是Apple崩溃报告,但我不能再出现:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x1000000013ed199e
0 Foundation 0x0000000182f3b4e8 ____addOperations_block_invoke607 + 524 (NSOperation.m:193)
1 Foundation 0x0000000182f3b488 ____addOperations_block_invoke607 + 428 (NSOperation.m:204)
2 Foundation 0x0000000182f26170 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:usingBlock:] + 672 (NSKeyValueObserving.m:2406)
3 Foundation 0x0000000182e7afc0 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] + 64 (NSKeyValueObserving.m:2432)
4 Foundation 0x0000000182f392e4 __addOperations + 1400 (NSOperation.m:2100)
Run Code Online (Sandbox Code Playgroud)
谢谢!
nsoperationqueue ×10
nsoperation ×7
objective-c ×4
ios ×3
memory-leaks ×2
afnetworking ×1
cocoa ×1
cocoa-touch ×1
concurrency ×1
crash ×1
drawrect ×1
image ×1
iphone ×1
nsthread ×1