- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我创建了一个实现一些方法的类。这些方法由另一个类调用,并通过 NSBlockOperation 进行管理。
我的 NSBlockOperation 工作正常,我在尝试计算变量时遇到问题:
EXC_BAD_ACCESS
我在互联网上做了很多研究,this是最接近我的问题的一个。我试着像 sugerito 那样做,但你遇到了同样的问题。
你有什么建议吗?
编辑:
这是堆栈跟踪:
2015-05-09 15:24:45.976 OutParameters[12326:743087] Stack trace : (
0 OutParameters 0x000000010e5d6602 -[ListOperation _method1:] + 194
1 OutParameters 0x000000010e5d646f __25-[ListOperation method1:]_block_invoke + 95
2 Foundation 0x000000010e74257f __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 7
3 Foundation 0x000000010e6830b2 -[NSBlockOperation main] + 98
4 Foundation 0x000000010e665774 -[__NSOperationInternal _start:] + 645
5 Foundation 0x000000010e665383 __NSOQSchedule_f + 184
6 libdispatch.dylib 0x00000001113f4614 _dispatch_client_callout + 8
7 libdispatch.dylib 0x00000001113db6a7 _dispatch_queue_drain + 2176
8 libdispatch.dylib 0x00000001113dacc0 _dispatch_queue_invoke + 235
9 libdispatch.dylib 0x00000001113de3b9 _dispatch_root_queue_drain + 1359
10 libdispatch.dylib 0x00000001113dfb17 _dispatch_worker_thread3 + 111
11 libsystem_pthread.dylib 0x0000000111761637 _pthread_wqthread + 729
12 libsystem_pthread.dylib 0x000000011175f40d start_wqthread + 13
)
修改后的代码:
- (IBAction)testCallMethod:(id)sender {
NSString * output;
[self.listOperationObj method1:&output];
NSLog(@"Output: %@", output);
}
和
@interface ListOperation : NSObject
-(void)method1:(NSString**)output;
@end
#define MAX_OPERATIONS 10
//define a log-level
static int logLevel = CSLOG_LEVEL_INFO;
@interface ListOperation ()
// Tail used to synchronize the methods
@property NSOperationQueue *queue;
@end
#pragma mark - Public methods
@implementation ListOperation
- (id)init {
self = [super init];
if(self) {
_queue = [NSOperationQueue new];
if(_queue) {
[_queue setMaxConcurrentOperationCount:1];
}else {
NSLog(@"TokenMgr creation failed: error creating operation queue");
self = nil;
}
}
return self;
}
-(void)method1:(NSString *__autoreleasing *)output{
LOGFSTART
if([self _isQueueFull] == FALSE) {
WEAK
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
STRONG
[strongSelf _method1:output];
}];
[self.queue addOperation:operation];
[operation waitUntilFinished];
}
else {
LOGE(@"TokenMgr's queue is full, aborting operation");
}
LOGFEND
}
#pragma mark - private methods
-(void)_method1:(NSString *__autoreleasing *)output{
std::string testString = "try put string";
*output = [NSString stringWithUTF8String:testString.c_str()];
}
- (BOOL) _isQueueFull {
return self.queue.operationCount > MAX_OPERATIONS;
}
@end
如果我反复按下按钮,这个更改会给我同样的错误。
最佳答案
眼前的问题与方 block 无关。你有一个代码片段说:
- (IBAction)testCallMethod:(id)sender {
NSString *__autoreleasing * output;
[self.listOperationObj method1:output];
NSLog(@"Output: %@", *output);
}
那是行不通的,因为 output
不会指向有效的内存地址,当您尝试使用 *output = ...
取消引用未初始化的指针时,它会崩溃。
相反,那应该是:
- (IBAction)testCallMethod:(id)sender {
NSString *output;
[self.listOperationObj method1:&output];
NSLog(@"Output: %@", output);
}
现在 output
引用了一个真正的 NSString *
指针,您可以用对对象的引用来填充它。
还有第二个更深层次的问题,即对操作中实例化的对象使用 * __autoreleasing *
引用。操作有自己的自动释放池,因此在 testCallMethod
中使用对象时会出现竞争条件。
相反,人们通常使用完成 block 将数据传回给调用者。因此:
- (IBAction)testCallMethod:(id)sender {
[self.listOperationObj method2:^(NSString *output) {
NSLog(@"Output: %@", output);
}];
}
和
- (void)method2:(void (^)(NSString *))completionHandler {
LOGFSTART
if([self _isQueueFull] == FALSE) {
WEAK
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
STRONG
[strongSelf _method2:completionHandler];
}];
[self.queue addOperation:operation];
// [operation waitUntilFinished]; // not needed any more
}
else {
LOGE(@"TokenMgr's queue is full, aborting operation");
}
LOGFEND
}
-(void)_method2:(void (^)(NSString *))completionHandler {
std::string testString = "try put string";
NSString *output = [NSString stringWithUTF8String:testString.c_str()];
completionHandler(output);
}
请注意,顺便说一下,这也解决了您的示例的另一个问题,即您必须在其中放置一个 waitUntilFinished
调用。您永远不应从主线程调用 waitUntilFinished
。如果您像上面那样使用完成 block ,则不再需要。
关于ios - NSBlockOperation EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30140318/
为了避免在 Objective-C 中使用 NSBlockOperation 时发生内存泄漏,我们必须将变量声明为 weak 以便能够引用 block 内的 block 操作(如果需要则取消),通常如
我创建了一个实现一些方法的类。这些方法由另一个类调用,并通过 NSBlockOperation 进行管理。 我的 NSBlockOperation 工作正常,我在尝试计算变量时遇到问题: EXC_BA
我正在学习 NSOperations 和 NSOperationQueue。 我有一组 NSBlockOperation:“UPLOAD”和“DELETE”。删除必须在执行前等待上传完成。 我希望发生
在检查我的代码时,我发现在很多地方我都假设调用 [NSBlockOperationInstance start]; 将在主线程上启动此操作。我不知道我为什么这么想,但无论如何我都不应该这么确定。我检查
我正在进入 NSBlockOperation 并且我有一些问题。值得注意的是,documentation对于 addExecutionBlock 说: Discussion The specified
由于我目前正在处理 Web 服务调用和数据库检索,所以我偶然发现了 NSBlockOperation 未启动的问题。 但是,首先要稍微解释一下。主要目标是拥有一个由以下操作组成的操作队列: 操作 #1
我在引用 block 本身内的“NSBlockOperation”时遇到麻烦。我需要检查操作是否被取消,并且似乎在启用 ARC 的项目中运行时,对“searchOperation”的任何访问都会泄漏。
我正在尝试在后台线程上发出网络请求,并且我决定使用 NSBlockOperations。我正在使用 ADNKit处理我的获取请求。这是代码: - (void)reloadPosts { dis
我扩展了 NSOperationQueue 以允许添加带有特定 NSString 作为标识符的 NSBlockOperation。 标识符值保存在用作注册表的 NSMutableArray 中。这就是
我有一个长时间运行的循环,我想使用 NSOperation 在后台运行。我想使用一个 block : NSBlockOperation *operation = [NSBlockOperation b
我有一个问题。我有以下代码: NSBlockOperation *op=[NSBlockOperation blockOperationWithBlock:^{ [[ClassA sh
我有一个 UITableView,其中每个部分都包含一行,每一行都包含一个 UICollectionView。 UITableView 是数据源并委托(delegate)给 Core Data 数据库
大家好,我很沮丧,因为我想改进代码,但我没有得到好的结果,这是我的代码 NSBlockOperation *blockOperation1 = [NSBlockOperation blockOpera
我必须从我的 RestAPI 同步一堆信息。我必须进行 6 次 RestAPI 调用才能完成工作。我用 Blocks 设计了 API 调用,如果有则返回 NSError。其中 3 个调用应该嵌套执
在我的项目中,我使用 NSBlockOperation 在后台线程上运行一个操作: var operationQueue = NSOperationQueue() var iop = NSBlockO
通常,当您创建一个 NSOperation 子类时,您负责在 -main 方法中创建和释放一个 NSAutoreleasePool。 当你使用 NSBlockOperation 时,你需要在 bloc
Foundation Framework 中共有三个操作类(NSOperation、NSInvocationOperation 和NSBlockOperation)。 我已经阅读了 concurren
我有一个应用程序目前使用 NSURLConnection 进行绝大多数网络。我想搬到 NSURLSession 因为 Apple 告诉我这是要走的路。 我的应用只是通过 + (NSData *)sen
我正在调试我的应用程序的一个有趣问题。 该应用程序针对iOS6.1,并且使用ARC。这是一些背景,因为它太大,无法复制粘贴到 SO 中。 有一个 Dashboard 类,它有一个 subview Co
我在使用 NSBlockOperation 并尝试访问 EKEventStore 时遇到问题。这是我的代码: 这段代码异步运行 NSBlockOperation *wordsOp =
我是一名优秀的程序员,十分优秀!