如何在objective-C中使用如何使用NSRunLoop并等待一些变量来改变值?
谢谢
我正在尝试在辅助线程中运行NSURLConnection async(目标是iOS4),为此我创建了一个并发的NSOperation,我想我差不多了,但我不清楚以下内容:
1)在iOS4中NSOperationQueue addOperation在新线程中启动操作,因为使用GCD,基于技术问答QA1712,但是,我的测试(模拟器和iPad)显示始终在主线程上调用start(),任何想法,我需要在这里检查:如果在主线程上然后产生一个新的?
2)如果通过addOperation()在辅助线程上实际调用了start,那么我可以通过在当前NSRunLoop上进行调度来启动我的异步NSURLConnection:
[self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.connection start];
Run Code Online (Sandbox Code Playgroud)
像这里的LinkedImageFetcher示例,我不需要循环,直到完成:
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!isCompelted);
Run Code Online (Sandbox Code Playgroud)
3)假设我在主线程上调用自定义NSOperation start()并且2)是正确的,并且我在start()中生成一个新线程来调用我的自定义main()方法:
[NSThread detachNewThreadSelector:@selector(main) toTarget:self withObject:nil];
Run Code Online (Sandbox Code Playgroud)
在我的main()中,我需要运行当前的线程运行循环:
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!isCompelted);
Run Code Online (Sandbox Code Playgroud)
这是我在并发NSOperation中设法运行NSURLConnection的唯一实例,但我不确定我是否需要运行RunLoop,如果该线程由GCD提供为技术说明状态,我可以遵循逻辑2)或者我还需要运行线程的runloop吗?如何测试GCD提供的线程?
非常感谢任何解释
我想知道Apple是如何-setNeedsLayout运作的.
我已经知道它比直接调用更有效-layoutSubviews,因为我可能需要在方法中执行两次.
这正是我所需要的:-setNeedsValidation视图控制器的一些自定义.
但是如何实现这样的功能呢?
我有一个可以在Snow Leopard服务器上运行数天和数周的应用程序。它用于-[NSRunLoop runUntilDate:]“暂停”十秒钟,执行其任务,然后再次暂停。运行一个多小时后,我的应用程序崩溃并显示以下报告:
崩溃报告
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000013
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Application Specific Information:
objc_msgSend() selector name: release
Thread 0 Crashed: Dispatch queue: com.apple.main-thread
0 libobjc.A.dylib 0x00007fff84cfef0c objc_msgSend + 40
1 com.apple.CoreFoundation 0x00007fff84e363d1 __CFRunLoopDoSources0 + 1361
2 com.apple.CoreFoundation 0x00007fff84e345c9 __CFRunLoopRun + 873
3 com.apple.CoreFoundation 0x00007fff84e33d8f CFRunLoopRunSpecific + 575
4 com.apple.Foundation 0x00007fff83e73b74 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 270
5 com.apple.Foundation 0x00007fff83ebf19a -[NSRunLoop(NSRunLoop) runUntilDate:] + 78
Run Code Online (Sandbox Code Playgroud)
乍一看,我以为我的NSRunLoop对象不再有效,因此releaseCF中深处的消息会导致崩溃。但是,我认为情况并非如此,因为我之前获得了对currentRunLoop对象的引用。
崩溃时间在1到1.5小时之间变化,但是我无法确定是什么原因造成的。由于我不确定下一步该怎么做,因此将不胜感激任何评论或意见或调试想法。 …
在Apple的MVCNetworking示例代码中,NetworkManager该类包含此方法以在专用于网络活动的辅助线程中维护运行循环(以便NSURLConnection异步运行):
- (void)networkRunLoopThreadEntry
{
while(YES) {
NSAutoreleasePool *pool;
pool = [[NSAutorelease alloc] init];
[[NSRunLoop currentRunLoop] run];
[pool drain];
}
}
Run Code Online (Sandbox Code Playgroud)
因为run如果没有连接到运行循环源方法立即退出,这看起来像一个无限while这是会无谓地消耗CPU资源,如果目前没有连接到运行循环NSURLConnection的循环.
另一方面,为了保持运行循环活动,一些人 建议在运行循环中安排一个空端口:
- (void)networkRunLoopThreadEntry
{
NSAutoreleasePool *pool = [[NSAutorelease alloc] init];
NSPort *port = [NSPort port];
[[NSRunLoop currentRunLoop] addPort:port forMode:NSRunLoopCommonModes];
[NSRunLoop run];
[pool drain];
}
Run Code Online (Sandbox Code Playgroud)
但是,在这种情况下,我担心该run方法永远不会退出,这意味着池永远不会被耗尽,这意味着在辅助线程中分配和自动释放的所有对象都将泄漏.
那是什么方式?
(对于上下文,和其他许多人一样,我正在尝试将异步封装NSURLConnection在a中NSOperation,这意味着它可以在主线程之外触发.此外,MVCNetworking示例代码,以及WWDC 2010会话Network Apps for iPhone操作系统,似乎建议有一个专用于网络传输的独特辅助线程以防止主线程上的延迟.)
NSRunLoop有两个api:
- (BOOL)runMode:(NSString *)mode beforeDate:(NSDate *)limitDate
Run Code Online (Sandbox Code Playgroud)
和
- (void)acceptInputForMode:(NSString *)mode beforeDate:(NSDate *)limitDate
Run Code Online (Sandbox Code Playgroud)
我的意思是它们是相同的,除了返回值,还是有其他差异?
我试图了解 iOS 中的多线程编程。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
, ^{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (connection == nil) {
NSLog(@"Request failed");
} else {
NSLog(@"Request sent");
}
[[NSRunLoop currentRunLoop] run];//How does this work?
});
Run Code Online (Sandbox Code Playgroud)
这段代码工作正常,我得到了预期的回调。
提到“运行”方法,“将接收器置于永久循环中,在此期间它处理来自所有附加输入源的数据。”
现在,在上面的代码中,我没有将任何源附加到 runLoop。它是如何工作的?
multithreading objective-c grand-central-dispatch nsrunloop ios
我有一个在 5 秒内触发的计时器添加到全局队列中,尽管我在 2 秒后使其无效,运行循环直到 5 秒才会终止。在以下代码段中,backgroundTimer 是一个实例 var,而 run 是一个成员函数。以下代码有什么问题阻止了运行循环终止。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
_backgroundTimer = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(run) userInfo:nil repeats:NO];
[ [NSRunLoop currentRunLoop] addTimer:_backgroundTimer forMode:NSRunLoopCommonModes];
[[NSRunLoop currentRunLoop] run];
NSLog(@"Run loop terminated");
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[_backgroundTimer invalidate];
_backgroundTimer=nil;
});
Run Code Online (Sandbox Code Playgroud) 我用 RunLoop 做实验。我正在创建简单的 Mac OS 控制台应用程序并且只调用一行代码。
RunLoop.current.run()
Run Code Online (Sandbox Code Playgroud)
之后在调试导航器出现第二个线程。为什么?
我一直在阅读RunLoopsApple文档中的几天以及来自Google搜索的内容.我在RunLoops很大程度上理解了这个概念,但我仍然没有回答一些基本问题RunLoops.
Runloop运作?是否类似while循环在某个系统级别运行?请为我提供一些指示..
nsrunloop ×10
objective-c ×7
cocoa ×3
ios ×3
macos ×2
cocoa-touch ×1
concurrency ×1
delay ×1
ios4 ×1
iphone ×1
nsoperation ×1
setter ×1
swift ×1
xcode ×1