Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c iOS启动后台线程_Objective C_Ios_Multithreading_Uikit_Core Foundation - Fatal编程技术网

Objective c iOS启动后台线程

Objective c iOS启动后台线程,objective-c,ios,multithreading,uikit,core-foundation,Objective C,Ios,Multithreading,Uikit,Core Foundation,我的iOS设备中有一个小sqlitedb。当用户按下按钮时,我从sqlite获取数据并将其显示给用户 这个获取部分我想在后台线程中完成(不阻塞UI主线程)。我是这样做的- [self-performSelectorInBackground:@selector(getResultSetFromDB:)with-Object:docId] 在抓取和一点处理之后,我需要更新UI。但是因为(作为一个好的实践),我们不应该从后台线程执行UI更新。我在主线程上调用选择器,如下所示- [self-perfor

我的iOS设备中有一个小sqlitedb。当用户按下按钮时,我从sqlite获取数据并将其显示给用户

这个获取部分我想在后台线程中完成(不阻塞UI主线程)。我是这样做的-

[self-performSelectorInBackground:@selector(getResultSetFromDB:)with-Object:docId]

在抓取和一点处理之后,我需要更新UI。但是因为(作为一个好的实践),我们不应该从后台线程执行UI更新。我在主线程上调用
选择器
,如下所示-

[self-performSelectorOnMainThread:@selector(showResults),对象:nil waitUntilDone:NO]

但我的应用程序在第一步就崩溃了。i、 e.启动后台线程。这不是在iOS中启动后台线程的方法吗

更新1:
[自执行选择背景…
之后,我得到了这个堆栈跟踪,没有任何信息

更新2:我甚至尝试过,像这样启动一个后台线程-
[NSThread detachNewThreadSelector:@selector(getResultSetFromDB:)toTarget:self with Object:DocId];
但我仍然得到相同的堆栈跟踪

我要澄清的是,当我在主线程上执行此操作时,一切都会顺利运行

更新3这是我试图从后台运行的方法

- (void)getResultSetFromDB:(NSMutableArray *)toProceessDocids
{
    SpotMain *mirror = [[SpotMain alloc] init];
    NSMutableArray *filteredDocids = toProceessDocids;

    if(![gMediaBucket isEqualToString:@""])
        filteredDocids = [mirror FetchDocIdsForMediaBucketWithDocID:filteredDocids mBucket:gMediaBucket numRes:-1];
    if(![gMediaType isEqualToString:@""])
        filteredDocids = [mirror FetchDocIdsForMediaType:filteredDocids mediaType:gMediaType numRes:-1];
    if(![gPlatform isEqualToString:@""])
        filteredDocids = [mirror FetchDocIdsForPlatformID:filteredDocids platformId:@"1" numRes:-1];

    self.resultSet = [mirror FetchObjectFromDocid:filteredDocids];
    [filteredDocids release];
    [mirror release];

    [self performSelectorOnMainThread:@selector(showResults) withObject:nil waitUntilDone:NO];
    return;
}
启用以了解要释放并访问的对象。 然后检查
getResultSetFromDB:
是否与此有关。还要检查
docids
中是否有任何内容,以及它是否被保留


通过这种方式,您可以确保没有任何错误。

如果您使用
performSelectorInBackground:withObject:
生成新线程,则执行的选择器负责设置新线程的自动释放池、运行循环和其他配置详细信息–请参阅《Apple线程编程指南》中的

不过,您最好使用:

GCD是一种较新的技术,在内存开销和代码行方面效率更高



更新了,建议对上述代码进行修改,使其更简单,并跟上苹果最新的GCD代码示例。

iOS附带的默认sqlite库未使用上的sqlite_THREADSAFE宏编译。这可能是代码崩溃的原因。

Swift 2.x回答:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
        self.getResultSetFromDB(docids)
    }

实际上,使用GCD很容易。典型的工作流程如下所示:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
    dispatch_async(queue, ^{
        // Perform async operation
        // Call your method/function here
        // Example:
        // NSString *result = [anObject calculateSomething];
                dispatch_sync(dispatch_get_main_queue(), ^{
                    // Update UI
                    // Example:
                    // self.myLabel.text = result;
                });
    });

有关GCD的更多信息,您可以查看一下

您得到了什么错误/崩溃日志?请查看我的更新…您可以显示您在后台调用的方法吗?并确保对象
docids
被保留。是的,
docids
retain
。我已将其作为
@属性(非原子,retain)放入
.h
NSMutableArray*docids;
不要在方法前面加上
get
;那应该是
resultSetFromDB:
请复制您使用的在主线程上平稳运行的行。我从主线程使用它&至少它会命中该方法,而不是突然崩溃-
[self-getResultSetFromDB:docids]
你启用了我告诉你的吗?在这行中放置一个断点:SpotMain*mirror=[[SpotMain alloc]init];并告诉我它是否命中,如果命中,哪行崩溃。请启用僵尸,这样我们就可以得到一个清晰的错误日志。是的,我启用了僵尸。我得到这个-`2011-08-14 12:49:42.697 FLO[16211:707]***-[FMResultSet release]:消息已发送到解除分配的实例0x2bff80 2011-08-14 12:49:42.697 FLO[16211:1607]***\uu NSAutoreleaseNoPool():类uu NSCFData的对象0x2c0cc0在没有池的情况下自动删除-只是泄漏
。另外,当我尝试从后台线程调用此方法时,我没有到达
SpotMain*mirror…`,它在进入后台线程后不久崩溃…酷!不知道这一点。这是否适用于
[NSThread detachNewThreadSelector:@selector….
也是?是的。根据Apple文档,调用
performSelectorInBackground:withObject:
“与调用
detachNewThreadSelector:toTarget:withObject:
(无符号长)之间有区别吗NULL
0
在这个问题上?@Sti来自apple Dev:注意:dispatch_get_global_queue函数的第二个参数是为将来的扩展保留的。现在,这个参数应该始终传递0。然后我应该使用performSelectorOnMainThread使用操作结果更新UI,还是有更一致的方法更新UI有GCD吗?
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
    dispatch_async(queue, ^{
        // Perform async operation
        // Call your method/function here
        // Example:
        // NSString *result = [anObject calculateSomething];
                dispatch_sync(dispatch_get_main_queue(), ^{
                    // Update UI
                    // Example:
                    // self.myLabel.text = result;
                });
    });