标签: nsrunloop

如何退出[NSRunLoop runUntilDate]?

我正在编写一个必须与通过USB连接的设备进行通信的应用程序.应用程序在固定时间从设备轮流发送和接收数据.所有Rx/Tx都发生在一个单独的线程中,否则UI将被阻止.基本结构看起来基本上是这样的.(自动释放池和省略的东西)

-(void)comThread:(id)arg {
  while(state == kIsConnected) {
    // let timers run
    [runLoop runUntilDate:[NSDate distantFuture]];
    // handle data
    if(rxTxState == kRx) {
      // do some stuff to pass data to upper layers
      rxTxState = kTx;
    }
    if(rxTxState == kTx) {
      // do some stuff to send data
      rxTimeoutTimer = [NSTimer scheduledTimer....];
    }
  } 
}
Run Code Online (Sandbox Code Playgroud)

在发送数据之后,应用程序等待接收数据或者rxTimeoutTimer发送导致重新发送数据包的数据.rx操作有效,因为底层使用异步系统调用并调用一个看起来基本像这样的rx处理程序.

-(void)receiveData:(NSData*)data{
  [rxQueue addObject:data];
  [rxTimeoutTimer invalidate];  // cancel timeout
}
Run Code Online (Sandbox Code Playgroud)

有一种(简单的)[runLoop runUntilDate:]退出方式receiveData:吗?Apple文档说删除所有计时器源并不能保证RunLoop退出.我读了一些关于打电话的事情,performSelector:onThread:...但它要么不起作用,要么我没有明白这一点.

谢谢.

macos cocoa nsthread nsrunloop

3
推荐指数
2
解决办法
5838
查看次数

函数sleep()和[[NSRunLoop currentRunLoop] runUntilDate]的使用差异

请考虑以下代码:

在第一个中,我调用一个创建动画的函数.我以一定的时间间隔做到这一点:

start:;

[self animationMethod];

[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]];
//sleep(3);

goto start;
Run Code Online (Sandbox Code Playgroud)

在第二个我创建一个动画

- (void)animationMethod
 {
  CAKeyframeAnimation *myAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
CGMutablePathRef curvedPath             = CGPathCreateMutable();

CGPathMoveToPoint(curvedPath, NULL, start.x, start.y);
CGPathAddCurveToPoint(curvedPath, NULL, fcp.x, fcp.y, scp.x , scp.y, end.x, end.y); 

myAnimation.path                = curvedPath;
myAnimation.duration            = flight_duration;
myAnimation.removedOnCompletion = NO;
myAnimation.delegate            = self;  
myAnimation.fillMode            = kCAFillModeForwards;

[myAnimation setValue:identifier forKey:@"id"];

[flyingBug addAnimation:myAnimation forKey:@"bug_flight"];

CGPathRelease(curvedPath);
 }
Run Code Online (Sandbox Code Playgroud)

第三个是委托方法,我用来检查一切正常:

- (void)animationDidStart:(CAAnimation *)anim
{

    NSLog(@"ANIMATION DID START");
}
Run Code Online (Sandbox Code Playgroud)

因此,当我使用NSRunLoop它工作正常时,调用委托方法,但如果我尝试使用sleep(3)函数,那么委托方法不会被调用.

我的问题:

1)你能解释一下NSRunLoop和sleep()之间的区别吗?为什么在使用sleep()时不调用委托方法?

2)也许第三种可能的方法更好用?

iphone sleep objective-c nsrunloop

3
推荐指数
1
解决办法
2835
查看次数

NSRunLoop正在消耗大量的CPU和内存

我有一个无限循环驱动我的工作线程.

-(void) myThread
{
    NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];   
    while(![myThread isCancelled])
    {
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:600]];
    }
    [pool release];
}
Run Code Online (Sandbox Code Playgroud)

但有时候这些线程占用了很多CPU(50-100%)和内存(1.5GB).当我在这种状态下对应用程序进行采样时,我得到了以下跟踪

    453 +[NSDate dateWithTimeIntervalSinceNow:]
          309 -[__NSPlaceholderDate initWithTimeIntervalSinceReferenceDate:]
            295 CFDateCreate
              268 _CFRuntimeCreateInstance
                115 malloc_zone_malloc
                  64 __spin_lock
                    64 __spin_lock
                  43 szone_malloc
                    22 tiny_malloc_from_free_list
                      22 tiny_malloc_from_free_list
                    19 szone_malloc
                    2 spin_unlock
                      2 spin_unlock
                  4 malloc_zone_malloc
                  3 dyld_stub__spin_unlock
                    3 dyld_stub__spin_unlock
                  1 dyld_stub__spin_lock
                    1 dyld_stub__spin_lock
                99 __bzero
                  99 __bzero
                29 malloc_size
                  23 szone_size
                    23 szone_size
                  6 malloc_size
                13 CFAllocatorAllocate
                  13 CFAllocatorAllocate
                12 _CFRuntimeCreateInstance
              20 CFDateCreate
              4 CFDateGetTypeID …
Run Code Online (Sandbox Code Playgroud)

cocoa objective-c cfrunloop nsrunloop

3
推荐指数
1
解决办法
1550
查看次数

"阻塞"主线程(dispatch_get_main_queue())和(或不)定期运行currentRunLoop - 有什么区别?

我有以下代码:

- (void)test_with_running_runLoop {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    NSTimeInterval checkEveryInterval = 0.05;

    NSLog(@"Is main queue? : %d", dispatch_get_current_queue() == dispatch_get_main_queue());

    dispatch_async(dispatch_get_main_queue(), ^{
        sleep(1);
        NSLog(@"I will reach here, because currentRunLoop is run");
        dispatch_semaphore_signal(semaphore);
    });

    while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW))
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:checkEveryInterval]];

    NSLog(@"I will see this, after dispatch_semaphore_signal is called");
}

- (void)test_without_running_runLoop {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    NSLog(@"Is main queue? : %d", dispatch_get_current_queue() == dispatch_get_main_queue());

    dispatch_async(dispatch_get_main_queue(), ^{
        sleep(1);
        NSLog(@"I will not reach here, because currentRunLoop is not run");
        dispatch_semaphore_signal(semaphore);
    }); …
Run Code Online (Sandbox Code Playgroud)

queue semaphore objective-c nsrunloop ios

3
推荐指数
1
解决办法
3825
查看次数

[UIApplication sendEvent:]是否在NSRunLoop中执行?

我读了关于runloop的这个苹果文档:

运行循环是一个事件处理循环,用于调度工作并协调传入事件的接收...运行循环从两种不同类型的源接收事件.输入源提供异步事件...定时器源提供同步事件......

现在我知道performSelector:withObject:afterDelay:NSTimer在runloop中运行.

该文档未提及触摸事件作为输入源.我想知道:

Q1:[UIApplication sendEvent:]在某些默认的runloop中也会通过run 发送触摸事件吗?
Q2:如果Q1的答案为YES,那么默认的runloop是否是相同的runloop句柄performSelector:withObject:afterDelay:NSTimer事件?

cocoa-touch objective-c nsrunloop ios

3
推荐指数
1
解决办法
2075
查看次数

为什么我需要 NSRunLoop 来运行计时器?

我购买了 Objective-C 的 Big Nerd Ranch Guide,但有一些NSRunLoop我想不通的地方。

这是书中的一段代码:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 
                                                  target:logger
                                                selector:@selector(updateLastTime:)
                                                userInfo:nil
                                                 repeats:YES];
[[NSRunLoop currentRunLoop] run];
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么我需要为要处理NSRunLoopNSTimer对象放置一个?为什么它需要在最后,而不是开始?

为什么它不像其他函数或对象的方法那样我只需要调用一个函数来处理它并登录到控制台?

我真的很想弄清楚这里每个细节的每个逻辑。

cocoa nstimer nsrunloop

3
推荐指数
1
解决办法
666
查看次数

可可中的 NSRunLoops?

假设我有 2 个线程,一个是主线程,另一个是辅助线程。主线程使用得最多,但有时(很少)我希望辅助线程根据主线程的调用做一些工作。大多数时候辅助线程应该休眠。现在经过一些搜索,我明白了这样做的方法是使用 runLoops。所以我试图阅读苹果的文档(http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW5 )

但在我看来它非常复杂,我在那里过得很艰难。有没有一种优雅而简单的方法来实现我所描述的?我可以运行和使用任何类似的 runLoop 代码示例吗?

谢谢

iphone cocoa multithreading nsthread nsrunloop

2
推荐指数
1
解决办法
788
查看次数

Runloop 和线程的区别?

  • 什么是运行循环?
  • 和线程有什么区别?
  • 哪些地方需要使用 run loop,哪些地方不用?

objective-c nsthread nsrunloop

2
推荐指数
1
解决办法
1444
查看次数

如何测试是否已触发UIControlEvents

我有一个实现自定义的库UIControl,其方法是.valueChanged在调用时触发事件.我想测试该行为的方法.

我的自定义控件:

class MyControl: UIControl {
    func fire() {
        sendActions(for: .valueChanged)
    }
}
Run Code Online (Sandbox Code Playgroud)

而且测试:

import XCTest

class ControlEventObserver: NSObject {
    var expectation: XCTestExpectation!

    init(expectation anExpectation: XCTestExpectation) {
        expectation = anExpectation
    }

    func observe() {
        expectation.fulfill()
    }
}

class Tests: XCTestCase {
    func test() {
        let myExpectation = expectation(description: "event fired")
        let observer = ControlEventObserver(expectation: myExpectation)
        let control = MyControl()
        control.addTarget(observer, action: #selector(ControlEventObserver.observe), for: .valueChanged)
        control.fire()
        waitForExpectations(timeout: 1) { error in
            XCTAssertNil(error)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是observe …

selector nsrunloop ios xctest swift

2
推荐指数
1
解决办法
800
查看次数

iOS RunLoop 和 DispatchQueue.main.async

为什么print("2")在下面的代码中永远不会调用该部分?我认为内部main.async会将块推入主循环的队列中,然后RunLoop.run执行它,但显然情况并非如此。(它打印1runrunrun等)

另外,如果我删除外部块main.async,然后直接运行该块中的代码(仍在主队列上,在viewDidLoad新的单视图应用程序中),那么内部main.async块就会被执行(打印1,,run2。为什么这一变化会产生如此大的差异?

var x = -1
DispatchQueue.main.async {   //  comment out this line for question #2
    print("1")
    x = 1
    DispatchQueue.main.async {
        print("2")
        x = 2
    }
    while x == 1 {
        print("run")
        RunLoop.main.run(mode: .default, before: Date() + 1)
    }
}   //  comment out this line for question #2
Run Code Online (Sandbox Code Playgroud)

nsrunloop ios dispatch-queue

2
推荐指数
1
解决办法
1507
查看次数