我是ios开发的新手.我有以下问题:
这两者之间有什么不同.
我知道当我们使用performSelectorInBackground时,我们创建了一个新的NSThread.但是当我们使用dispatch_group_async时却不一样吗?因为如果我们创建多个dispatch_group_async,则意味着我们需要在队列中提交多个块.这些块可能在不同的队列上运行.因此,当我们创建多个dispatch_group_async时,是否意味着我们创建了一个新线程?(因为块可能在不同的队列上运行)(我对NSThread和阻塞队列感到困惑.....)
谢谢!!
以下是我所了解和理解的事情:
全局队列是一个并发队列,可以将任务分派给多个线程.执行任务的顺序无法保证.例如:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), {
for (int i; i<10; i++) {
doTask()
}
})
Run Code Online (Sandbox Code Playgroud)
如果我想调度到串口队列,我可以使用
dispatch_async(dispatch_queue_create("my.serial.queue", nil) {
...
}
Run Code Online (Sandbox Code Playgroud)
每次只有一个任务被分派到一个线程并被执行.订单是FIFO.
=====我感到困惑和不完全理解=======
主线程有一个NSRunLoop,在主线程中循环任务.我想知道调度队列和运行循环之间的关系是什么?我可以理解它,如果将任务调度到主线程,主线程的NSRunLoop获取调度任务并执行它吗?
将任务分派给多个线程的全局队列怎么样?iOS/OSX系统是否自动创建线程,还为每个线程创建NSRunLoop?然后每个线程中的运行循环从全局队列中获取调度任务并执行它?
谁知道线程?do dispatch_async()和dispatch_sync()function知道哪个线程要调度任务,或者队列知道哪个线程要调度任务?
有没有办法以编程方式从调度队列中获取线程的NSRunLoop对象(调度任务的对象)?(这个问题与问题3有关)
multithreading nsthread grand-central-dispatch nsrunloop ios
我为NSThread和Grand Central Dispatch(GCD)创建了一些测试代码:
- (void)doIt:(NSNumber *)i
{
sleep(1);
NSLog(@"Thread#%i", [i intValue]);
}
- (IBAction)doWork:(id)sender
{
for (int i = 0; 10 > i; i++) {
NSNumber *t = [NSNumber numberWithInt:i];
[NSThread detachNewThreadSelector:@selector(doIt:) toTarget:self withObject:t];
}
sleep(1);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(10, queue, ^(size_t i) {
sleep(1);
NSLog(@"GCD#%u",(int)i);
});
}
Run Code Online (Sandbox Code Playgroud)
结果如下:
2011-04-13 19:41:07.806 GDC[1494:5e03] Thread#0
2011-04-13 19:41:07.813 GDC[1494:6903] Thread#3
2011-04-13 19:41:07.812 GDC[1494:6403] Thread#2
2011-04-13 19:41:07.812 GDC[1494:5f03] Thread#1
2011-04-13 19:41:07.813 GDC[1494:6e03] Thread#4
2011-04-13 19:41:07.814 GDC[1494:7303] Thread#5
2011-04-13 19:41:07.814 GDC[1494:7803] Thread#6
2011-04-13 …Run Code Online (Sandbox Code Playgroud) 我知道UIView不是线程安全所以我不能在后台线程上添加一个视图,要解决这个问题,可以在后台线程上创建一个UIView然后将其添加到主线程上吗?
注意:我不在主线程上执行此操作的原因是因为我的实际代码要复杂得多,因此需要一段时间来创建所有视图并填充值.当我这样做时,我不希望UI变得无响应,所以我试图解决这个问题.
例如..
-(void)addLabel//called on background thread
{
UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(0,0,40,100)];
[label setText:@"example"]
[self.view performSelector:@selector(addSubview:) onThread:[NSThread mainThread] withObject:example waitUntilDone:YES];
}
Run Code Online (Sandbox Code Playgroud)
提前致谢.
我有一个工作线程,我想做一点任务,然后暂停并等待来自另一个线程的"ok,continue"命令,然后暂停和等待等.
用例是:控制对象是一个视图,我想显示有关工作线程内部发生的事情的信息,并允许我通过工作人员"单步"完成它的工作.
我工作中相当丑陋和沉重的事情是:
NSLog(@"paused");
paused = YES;
while (paused)
{
[NSThread sleepForTimeInterval:0.25];
}
NSLog(@".. continuing");
Run Code Online (Sandbox Code Playgroud)
......但我不禁想到必须有一个更好的方式,可能涉及NSLocks,或者其他一些.
评论,提示建议?
谢谢!
我想用多个参数创建一个Thread.可能吗?我有这个功能:
-(void) loginWithUser:(NSString *) user password:(NSString *) password {
}
我想将此函数称为选择器:
[NSThread detachNewThreadSelector:@selector(loginWithUser:user:password:) toTarget:self withObject:@"someusername" withObject:@"somepassword"]; // this is wrong
如何在这个detachNewThreadSelect函数上传递onObject参数的两个参数?
可能吗?
我想模拟与服务器的通信.由于远程服务器会有一些延迟,我想使用它上面的后台线程
[NSThread sleepForTimeInterval:timeoutTillAnswer];
Run Code Online (Sandbox Code Playgroud)
该线程是使用NSThread子类创建的并且已经启动...但是我注意到sleepForTimeInterval阻塞了主线程...为什么??? 默认情况下,NSThread不是backgroundThread吗?
这是线程的创建方式:
self.botThread = [[PSBotThread alloc] init];
[self.botThread start];
Run Code Online (Sandbox Code Playgroud)
更多信息:这是bot线程子类
- (void)main
{
@autoreleasepool {
self.gManager = [[PSGameManager alloc] init];
self.comManager = [[PSComManager alloc] init];
self.bot = [[PSBotPlayer alloc] initWithName:@"Botus" andXP:[NSNumber numberWithInteger:1500]];
self.gManager.localPlayer = self.bot;
self.gManager.comDelegate = self.comManager;
self.gManager.tillTheEndGame = NO;
self.gManager.localDelegate = self.bot;
self.comManager.gameManDelegate = self.gManager;
self.comManager.isBackgroundThread = YES;
self.comManager.logginEnabled = NO;
self.gManager.logginEnabled = NO;
self.bot.gameDelegate = self.gManager;
BOOL isAlive = YES;
// set up a run loop
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
[runloop addPort:[NSMachPort …Run Code Online (Sandbox Code Playgroud) 我在调试器的日志窗口中收到此警告:
CoreAnimation: warning, deleted thread with uncommitted CATransaction; set CA_DEBUG_TRANSACTIONS=1 in environment to log backtraces.
Run Code Online (Sandbox Code Playgroud)
我必须找出我的代码叫做CATransaction,所以我可以确保它在主线程上运行.我的代码不直接调用CATransaction.即搜索我的CATransaction代码没有任何结果.
在Xcode 5中,在环境中设置CA_DEBUG_TRANSACTIONS = 1的正确方法是什么?
提前感谢所有信息.
我正在尝试使用我在某处下载的类中的方法.程序执行继续时,该方法在后台执行.在此方法完成之前,我不想让程序继续执行.我怎么做?
要在主线程上执行"stuff",我应该使用dispatch_async还是performSelectorOnMainThread?是否有首选方式,正确/错误和/或最佳做法?
示例:我在NSURLConnection sendAsynchronousRequest:urlRequest方法块中执行某些逻辑.因为我正在做主要视图的东西,比如呈现UIAlertView我需要UIAlertView在主线程上显示.为此,我使用以下代码.
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// code snipped out to keep this question short
if(![NSThread isMainThread])
{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Oops!" message:@"Some Message" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
});
}
}];
Run Code Online (Sandbox Code Playgroud)
在同一个if(![NSThread isMainThread])声明中,我也称之为一些自定义方法.问题是,我应该dispatch_async使用上面使用的方法还是更好地使用performSelectorOnMainThread?例如,下面的完整代码:
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// code snipped …Run Code Online (Sandbox Code Playgroud) asynchronous objective-c nsthread grand-central-dispatch ios
nsthread ×10
ios ×6
objective-c ×5
cocoa-touch ×2
asynchronous ×1
background ×1
cocoa ×1
iphone ×1
nsrunloop ×1
uiview ×1
xcode5 ×1