Xcode 头文件搜索路径设置

User Header Search Paths = $(SRCROOT)    // recursive
Always Search User Paths = YES

NSNotification 的同步运行

相同线程

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"viewWillAppear");
    [[NSNotificationCenter defaultCenter] addObserverForName:@"Test_NOTIFY" object:self queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
        NSLog(@"In Observer: Thread = %@", [NSThread currentThread]);
        [NSThread sleepForTimeInterval:5];
    }];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:@"Test_NOTIFY" object:self];
    
    NSLog(@"viewDidLoad Finished");
}

不同线程

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"viewWillAppear");
    [[NSNotificationCenter defaultCenter] addObserverForName:@"Test_NOTIFY" object:self queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
        NSLog(@"In Observer: Thread = %@", [NSThread currentThread]);
        [NSThread sleepForTimeInterval:5];
    }];
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"post: Thread = %@", [NSThread currentThread]);
        [[NSNotificationCenter defaultCenter] postNotificationName:@"Test_NOTIFY" object:self];
        NSLog(@"Post thread Finished");
    });
    
    NSLog(@"viewDidLoad finished");
}

异步还是用NSNotificationQueue吧

iOS 滑动调节音量和亮度

typedef NS_ENUM(NSInteger, MyPanType) {
    MyPanTypeNone,
    MyPanTypeBrightness,
    MyPanTypeVolume,
};

- (void)initGestureProcessor {
    _currentPanType = MyPanTypeNone;
    
    _panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureRecognized:)];
    [_panGestureRecognizer setMinimumNumberOfTouches:1];
    [_panGestureRecognizer setMaximumNumberOfTouches:1];
    _panGestureRecognizer.delegate = self;
    [self.view addGestureRecognizer:_panGestureRecognizer];
}


- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if (touch.view != self.view)
        return NO;
    return YES;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

- (MyPanType)detectPanTypeForPan:(UIPanGestureRecognizer *)panRecognizer {
    CGPoint location = [panRecognizer locationInView:self.view];
    CGFloat position = location.x;
    CGFloat viewWidth = 0.0;
    viewWidth = self.view.frame.size.width;
    
    MyPanType panType = MyPanTypeVolume;
    if (position < viewWidth / 2)
        panType = MyPanTypeBrightness;
    
    return panType;
}

- (void)panGestureRecognized:(UIPanGestureRecognizer *)panGestureRecognizer {
    CGFloat panDirectionY = [panGestureRecognizer velocityInView:self.view].y;
    
    if (panGestureRecognizer.state == UIGestureRecognizerStateBegan)
        _currentPanType = [self detectPanTypeForPan:panGestureRecognizer];
    
    if (_currentPanType == MyPanTypeVolume) {
        MPMusicPlayerController *musicPlayer = [MPMusicPlayerController applicationMusicPlayer];
        if (panDirectionY > 0)
            musicPlayer.volume -= 0.01;
        else
            musicPlayer.volume += 0.01;
        
    } else if (_currentPanType == MyPanTypeBrightness) {
        CGFloat brightness = [UIScreen mainScreen].brightness;
        if (panDirectionY > 0)
            brightness -= 0.01;
        else
            brightness += 0.01;
        
        if (brightness > 1.0)
            brightness += 1.0;
        else if (brightness < 0.0)
            brightness = 0.0;
        [[UIScreen mainScreen] setBrightness:brightness];
    }
    
    if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) {
        _currentPanType = MyPanTypeNone;
    }
}

ARC 转型 Bridge

__bridge

只做类型转换,不修改对象内存管理权

__bridge_retained / CFBridgeRetain

将ARC的管理对象转换为非ARC管理,同时把内存管理权转变为非ARC管理,需要使用CFRelease或者相关方法来释放对象

__bridge_transfer / CFBridgeRelease

将非ARC管理的对象转换为ARC管理,同时将内存管理权交给ARC

Git Branching Model

Alt none