ios开发-Part1杂七杂八大集合

1.CGRectGet**方法

CGRectGet** 共有如下8个方法, 用于对一个Rect进行处理;

方法 描述
CGRectGetMaxX 矩形的右边距
CGRectGetMaxY 矩形下边距
CGRectGetMidX 矩形中心点横坐标
CGRectGetMidY 矩形中心点纵坐标
CGRectGetMinX 矩形左边距
CGRectGetMinY 矩形上边距
CGRectGetWidth 矩形宽度
CGRectGetHeight 矩形高度

2.instancetype 和id

instancetype 和id的区别有如下三个:

  • instancetype在类型表示上,跟id一样,可以表示任何对象类型
  • instancetype只能用在返回值类型上,不能像id一样用在参数类型上
  • instancetype比id多一个好处:编译器会检测instancetype的真实类型(方法所在类的类型)

通过参考文献可以了解到,这是一个针对编译器的trick. 我们通常在编写一个类的时候,免不了编写返回为当前类对象的类,例如copy, init等方法. 如果这些方法返回类型直接指定为id, 则在使用的时候编译器不能确定你的返回值具体是什么类型, 因而会跳过一些必要的检查. instancetype 就是为了避免这种情况发生而产生的.

参考

objc 特征

3.View 动画

  1. animateWithDuration

    animateWithDuration为view的属性变化添加动画, 其声明方式:

    animateWithDuration:animations:
    animateWithDuration:animations:completion:
    animateWithDuration:delay:options:animations:completion:
    
    

    可以改变的属性包括
    frame, bounds, center, transform, alpha, backgroundColor, contentStretch;

    - (IBAction)showHideView:(id)sender
    

{
// Fade out the view right away
[UIView animateWithDuration:1.0
delay: 0.0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
thirdView.alpha = 0.0;
}
completion:^(BOOL finished){
// Wait one second and then fade in the view
[UIView animateWithDuration:1.0
delay: 1.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
thirdView.alpha = 1.0;
}
completion:nil];
}];
}
```
通过上面的例子,我们能够知道:

* 1)animateWithDuration方法是属于UIView 的类方法; 

* 2)在animations:后面的block中对view的设置即动画结束时的状态, 方法会自动计算中间过程;

从文档中,我们可以知道:

* 3)动画代码在另一个线程中执行;
* 4)当动画在执行过程中,如果某个view的属性被修改了,并不会影响动画的执行, 其处理方式是当前动画继续执行,并且以动画会调整到以新设置的属性为最终状态来变化;
* 5)如果想要重复执行多次, 可以通过重复次数加0.5的方式使其停留在最终状态;

[关于4) 5)的demo](https://github.com/talkfiled/resources/tree/master/codes/animation/animation)

除了改变一个View的属性值, 某些情况下还想控制两个view之间的切换动画, 可以通过如下两个方法实现view间的切换:

  1. transitionWithView
- (IBAction)displayNewPage:(id)sender
{
    [UIView transitionWithView:self.view
        duration:1.0
        options:UIViewAnimationOptionTransitionCurlUp
        animations:^{
            currentTextView.hidden = YES;
            swapTextView.hidden = NO;
        }
        completion:^(BOOL finished){
            // Save the old text and then swap the views.
            [self saveNotes:temp];
 
            UIView*    temp = currentTextView;
            currentTextView = swapTextView;
            swapTextView = temp;
        }];
}

如上代码实现了两个view currentTextViewswapTextView之间的 向上翻页切换效果, 翻页范围self.view 也就是说 transitionWithView的用于切换某个view下两个子类;

  1. transitionFromView

transitionFromView 的一个使用方法如下,

- (IBAction)displayNewPage:(id)sender
{
    [UIView transitionWithView:self.view
        duration:1.0
        options:UIViewAnimationOptionTransitionCurlUp
        animations:^{
            currentTextView.hidden = YES;
            swapTextView.hidden = NO;
        }
        completion:^(BOOL finished){
            // Save the old text and then swap the views.
            [self saveNotes:temp];
 
            UIView*    temp = currentTextView;
            currentTextView = swapTextView;
            swapTextView = temp;
        }];
}

transitionWithView相同transitionFromView也实现了两个view之间的切换, 不同的是, transitionWithView需要指定一个父view 实现view之间的切换,而transitionFromView不需要;
经过测试transitionFromView 的切换范围为FromView的父控件, 即:每次切换的刷新(变化,例如翻页的范围)范围为其父view

切换效果

动画效果 描述
UIViewAnimationOptionLayoutSubviews cell2
UIViewAnimationOptionAllowUserInteraction cell2
UIViewAnimationOptionBeginFromCurrentState cell2
UIViewAnimationOptionRepeat cell2
UIViewAnimationOptionAutoreverse cell2
UIViewAnimationOptionOverrideInheritedDuration cell2
UIViewAnimationOptionOverrideInheritedCurve cell2
UIViewAnimationOptionAllowAnimatedContent cell2
UIViewAnimationOptionShowHideTransitionViews cell2
UIViewAnimationOptionOverrideInheritedOptions cell2
UIViewAnimationOptionCurveEaseInOut cell2
UIViewAnimationOptionCurveEaseIn cell2
UIViewAnimationOptionCurveEaseOut cell2
UIViewAnimationOptionCurveLinear cell2
UIViewAnimationOptionTransitionNone cell2
UIViewAnimationOptionTransitionFlipFromLeft cell2
UIViewAnimationOptionTransitionFlipFromRight cell2
UIViewAnimationOptionTransitionCurlUp cell2
UIViewAnimationOptionTransitionCurlDown cell2
UIViewAnimationOptionTransitionCrossDissolve cell2
UIViewAnimationOptionTransitionFlipFromTop cell2
UIViewAnimationOptionTransitionFlipFromBottom cell2

参考

Animations

4.随机数生成

iOS 开发中可以通过如下四种方法获取随机数:

  1. rand

    rand 是标准c库中的一个方法, 根据一个seed返回一个范围在[0 - RAND_MAX]的随机数列(伪随机).
    srand 用于设定当前seed的值

    int main(void)
    

{
srand((unsigned int)time(0));; //将当前时间用作随机生成器种子
int random_variable = rand();
printf("Random value on [0,%d]: %d\n", RAND_MAX, random_variable);
}

```
  1. random

    random 也是标准c库中的方法, 用于返回一个返回再[0 - (2**31)-1]之间的随机数列(伪随机).
    rand相比,random更加随机,

    int main(void)
{
    srandom((unsigned int)time(0));; //将当前时间用作随机生成器种子
    int random_variable = random();
}
    
    ```
    
3. `arc4random`

    `arc4random`采用arc4加密的密钥流发生器(key stream generator employed by the arc4 cipher) 返回一个范围在[0 - (2**32)-1]之间的随机数列(伪随机).

    ```objc
    int main(void)
{
    // 不需要设置种子
    int random_variable = arc4random();
}
    
    ```

4. `arc4random_uniform(u_int32_t upper_bound)`

    `arc4random_uniform(u_int32_t upper_bound)`返回一个[0-upper_bound]之间的伪随机数列;

#### 参考
[arc4random](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/arc4random_uniform.3.html)  
[srand](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/rand.3.html#//apple_ref/doc/man/3/rand)


## 状态栏样式控制

`preferredStatusBarStyle ` view controller的方法, 用于指定状态栏的样式;

想要修改状态栏样式,可以通过重写该方法并返回对应的值. 有两个值可用:

* UIStatusBarStyleDefault: 深色样式, 当浅色背景时用;
* UIStatusBarStyleLightContent: 浅色样式, 深色背景时用;

## ios 方法大集合

#### kvc
KVC(Key-value coding)键值编码, 指的是IOS开发中,可以允许开发者通过Key名直接访问对象的属性, 或者给对象的属性复制. 而不需要调用明确的存取方法. 这样就可以在运行时修改对象的属性值,而不需要编译时确定;

重要的方法:

1. kvc 常用重要方法

    kvc 编程都是对NSObject 对象的扩展实现的, 因此所有继承制NSobject的类型都可以使用kvc;以下四个重要方法揭示了kvc编程的核心思想:
    
  • (nullable id)valueForKey:(NSString *)key;
    //通过Key来取值

  • (void)setValue:(nullable id)value forKey:(NSString *)key;
    //通过Key来设值

  • (nullable id)valueForKeyPath:(NSString *)keyPath;
    //通过KeyPath来取值

  • (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
    //通过KeyPath来设值


前两个方法揭示了kvc的核心思想, 即通过一个字符串 key来给对象赋值value,或者取出对象中的值;
后两个方法使用了keyPath, keyPath直译键路径, 用于确定自定义类属性中的属性;

```objc

    // 使用一
        [p1 setValue:@"20" forKey:@"age"];
        [p1 setValue:@"30" forKeyPath:@"age"];
        
    // 使用二
       // 实例化book对象
       Book *b1 = [[Book alloc] init];
       b1.bookName = @"吃货大全";
        
       p1.book = b1;
        
       // 通过kvc修改book的名字
       [p1 setValue:@"随便" forKeyPath:@"book.bookName"];

除了对NSObject 的基础使用,对于集合类,kvc也提供了一些方法;

/**
   kvc 和 字典
   字典里有的key值 -->  p1对象中一定要由对应的属性名
   字典里的key值 , 一定要和 对象中属性名保持一致
   */
   
   NSDictionary *dict = @{@"name":@"wangwu",@"age":@"40"};
   [p1 setValuesForKeysWithDictionary:dict];
   

- (NSDictionary<NSString *, id> *)dictionaryWithValuesForKeys:(NSArray<NSString *> *)keys;
输入一组key,返回该组key对应的Value,再转成字典返回,用于将Model转到字典。

/**
    kvc 和 数组
    根据keyPath 找到数组中对象的 name 属性, 并返回(数组)
    NSArray *nameArray = [array valueForKeyPath:@"name"];
*/
    Person *p2 = [[Person alloc] init];
    p2.name = @"yellow Mokey";     
    
    Person *p3 = [[Person alloc] init];
    p3.name = @"red dog";
    
    Person *p4 = [[Person alloc] init];
    p4.name = @"green chicken";
   
    NSArray *array = @[p2,p3,p4];
   
   // 把三个对象中的name 取出来
    NSArray *nameArray = [array valueForKeyPath:@"name"];
    NSLog(@"%@",nameArray);
    // 输出p2,p3,p4 的name组成的(NSString*) 数组;
  1. 异常处理

上面的代码都是正常情况下的使用方法, 在编码过程中异常处理是比不可少的, 因此ios还未kvc编程提供了一些常用的异常处理的方法:
+ (BOOL)accessInstanceVariablesDirectly; 一个属性用于表示在查找key的过程中如果没有找到key值,是否按照_key, _iskey, key, iskey的顺序搜索成员;

- (BOOL)validateValue:(inout id __nullable * __nonnull)ioValue forKey:(NSString *)inKey error:(out NSError **)outError;KVC提供属性值确认的API,它可以用来检查set的值是否正确、为不正确的值做一个替换值或者拒绝设置新值并返回错误原因。

- (nullable id)valueForUndefinedKey:(NSString *)key; 取值时, 当查询的key不存在时调用该方法返回值, 默认会抛出异常;

- (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key; 赋值时如果key值没找到调用该方法,默认抛出异常;

- (void)setNilValueForKey:(NSString *)key; 当给key赋值nil时调用, 默认抛出异常;

  1. 其他边边角角

验证 某个key对应的value是否合法- (BOOL)validateValue:(inout id __nullable * __nonnull)ioValue forKey:(NSString *)inKey error:(out NSError **)outError;

这个方法默认实现是去探测类中是否存在-(BOOL)validate<Key>:error:的方法, 如果存储在则调用,否则直接返回YES;

@implementation Address
// country的验证方法
-(BOOL)validateCountry:(id *)value error:(out NSError * _Nullable __autoreleasing *)outError{  //在implementation里面加这个方法,它会验证是否设了非法的value
    NSString* country = *value;
    country = country.capitalizedString;
    if ([country isEqualToString:@"Japan"]) {
        return NO;                                                                             //如果国家是日本,就返回NO,这里省略了错误提示,
    }
    return YES;
}
@end


NSError* error;
id value = @"japan";
NSString* key = @"country";// 默认会去调用validateCountry:方法
BOOL result = [add validateValue:&value forKey:key error:&error]; //如果没有重写-(BOOL)-validate<Key>:error:,默认返回Yes
if (result) {
    NSLog(@"键值匹配");
    [add setValue:value forKey:key];
}
else{
    NSLog(@"键值不匹配"); //不能设为日本,基他国家都行
}
NSString* country = [add valueForKey:@"country"];
NSLog(@"country:%@",country);
//打印结果 
2016-04-20 14:55:12.055 KVCDemo[867:58871] 键值不匹配
2016-04-20 14:55:12.056 KVCDemo[867:58871] country:China

参考

详解KVC

About Key-Value Coding

属性遍历

enumerateObjectsUsingBlock:方法是 NSArray的方法, 用于遍历数组中每个元素;
block 中可以通过设置stop 值确定是否继续遍历; 类似于for循环中break功能;

监听控件

开发中难免会与用户交互, 这就需要监听用户对于一个空间的交互, 开发中常见的实现交互的方式有:

  1. 拖线
    在storyboard 或者xib文件中对一个button控件脱线到代码文件的@implementation部分, 会自动创建一个方法来处理点击事件; 此时对应button控件的连接视图connection inspector Sent Event -> Touch Up Inside 会有一个指向代码的连接;
    20170506149400129896936.png

点击叉号可以删除该连接;

  1. 代码指定

通过控件对象的addTarget:action:forControlEvents:方法来实现对控件的监听;

[button addTarget:self
         action:@selector(didClickOptionButton:)
        forControlEvents:UIControlEventTouchUpInside];

如上代码中为button设置了一个@selector 方法, 该方法存在于self 中, 处理控件的UIControlEventTouchUpInside 事件;

  1. 手势监听;
  2. 方法重写;

调用某个对象的消息方法

从开始学洗objc就知道,这门开发语言是消息驱动的,通过消息的发送和接受执行消息的传递; 除了常规的方法调用,我们还可以通过NSInvocationperformSelector系列方法 来调用一个对象的方法;

  1. performSelector系列方法
`performSelector` 系列方法的声明在NSObject class和NSObject portocol 中均有; 通过`performSelector` 系列方法,可以设置方法执行的方式, 参数, 时间,所在线程等;

除了可以指定方法的执行方式以外, `performSelector` 与直接调用的区别还有编译器不会检查方法是否存在, 因此一个健壮的方式是使用`- (BOOL)respondsToSelector:(SEL)aSelector;` 方法判断类对象中是否有这个方法, 然后在发送执行消息; 值得一提的是`respondsToSelector:`的方法声明存在两个地方`Class NSProxy` 和`Protocol NSObject`中.


`Protocol NSObject` 中的方法
方法 描述
performSelector: 发送一个执行的消息
performSelector:withObject: 带一个参数
performSelector:withObject:withObject: 带两个参数
`Class NSObject` 中的方法
方法 描述
performSelector:withObject:afterDelay: 发送一个执行的消息,并且带参数,指定延迟时间
performSelector:withObject:afterDelay:inModes: 指定执行模式
performSelectorOnMainThread:withObject:waitUntilDone: waitUntilDone, 是否阻塞当前线程;
performSelectorOnMainThread:withObject:waitUntilDone:modes: --
performSelector:onThread:withObject:waitUntilDone: --
performSelector:onThread:withObject:waitUntilDone:modes: --
performSelectorInBackground:withObject: --

例子: mode 的使用

//mode 的使用
NSArray *arr = [NSArray arrayWithObject:NSDefaultRunLoopMode];

[self performSelector:@selector(sel:)
       withObject:@"active" 
      afterDelay:3 
      inModes:arr];

  1. NSInvocation

    使用performSelector可以完成大部分的消息传递操作, 但是如果参数超出2个限制,就不那么友好了. 解决办法是可以使用NSInvocation 类;

    1. NSInvocation的初始化和调用
      在官方文档中有明确说明,NSInvocation对象只能使用其类方法来初始化,不可使用alloc/init方法。它执行调用之前,需要设置两个方法:setSelector: 和setArgument:atIndex:
      同时文档中也说明NSInvocation是灵活的, 在invoke 一个对象之前,其签名, target和selector都是可以修改的;
- (void)viewDidLoad {
    [super viewDidLoad];
    SEL myMethod = @selector(myLog);
    //创建一个函数签名,这个签名可以是任意的,但需要注意,签名函数的参数数量要和调用的一致。
    NSMethodSignature * sig  = [NSNumber instanceMethodSignatureForSelector:@selector(init)];
    //通过签名初始化
    NSInvocation * invocatin = [NSInvocation invocationWithMethodSignature:sig];
    //设置target
    [invocatin setTarget:self];
    //设置selecteor
    [invocatin setSelector:myMethod];
    //消息调用
    [invocatin invoke];
    
}
-(void)myLog{
    NSLog(@"MyLog");
}
  1. NSInvocation的返回值
//方法一:
id res = nil;
if (signature.methodReturnLength != 0) {//有返回值
    //将返回值赋值给res
    [invocation getReturnValue:&res];
}
return res;

//方法二:
//可以通过signature.methodReturnType获得返回的类型编码,因此可以推断返回值的具体类型

参考

Class NSObject

Protocol NSObject

NSInvocation的基本用法

iOS NSInvocation应用与理解

inModels

NSInvocation的基本用法

iOS NSInvocation应用与理解

对话框

常见控件及其属性

UIScrollView

contentSize ScrollView的内容大小, 默认是CGSizeZero. 在设置的时候, contentSize需要比scrollView 的size 要大,否则没有滚动效果;

showsHorizontalScrollIndicatorshowsVerticalScrollIndicator, 两个BOOL 类型的值, 用于控制显示和吟唱横向/纵向指示器;

bounces, BOOL 类型值, 用于控制弹簧效果;

alwaysBounceHorizontalalwaysBounceVertical 两个BOOL类型值, 用于在bounces == YES的时候,控制contentSize小于ScrollView显示区域时( 不需要滚动)是否显示 横向/纵向的弹簧效果;

contentInset 一个UIEdgeInsets对象, 用于控制子View的内边距, 相当于增大了contentSize;

contentOffset, 一个CGPoint对象, 相对于子View的滚动(忽略contentInset);

minimumZoomScalemaximumZoomScale 属性, 用于控制最小和最大缩放倍数;

ScrollView不能滚动的原因:

  1. contentSizescrollView的size 小
  2. _scrollView.userInteractionEnabled = NO;
  3. _scrollView.scrollEnabled = NO;

delegate属性, 一个准守了UIScrollViewDelegate 协议的对象, 用于监听ScrollView的滑动;

在几乎所有的计算机和编程的教程中, 总是能看到各种设计模式, 但是仔细想想这些设计模式有那么重要吗? 这些看起来 "高大上" 术语是在帮助我们理解还是故意制造出来的行业壁垒? 我只能自己尽量避免使用我认为不必要的术语.

UIScrollViewDelegate , ScrollView的代理协议, 包括如下一些方法: 这些方法都是@optional


- (void)scrollViewDidScroll:(UIScrollView *)scrollView;

- (void)scrollViewDidZoom:(UIScrollView *)scrollView; 

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset;

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView;    
 
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;     
 
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView; 

- (nullable UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;     

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(nullable UIView *)view; 

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(nullable UIView *)view atScale:(CGFloat)scale; 

- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView;   

- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView;      

pagingEnabled BOOL 类型属性, 是否显示分页效果;分页效果以scrollView的宽度为基准,与子view的内容没有关系;分页效果忽略contentInset属性设置的边距;

一个测试用代码:

CGSize scrollViewSize = _scrollView.frame.size;
    
    for (int i = 0; i < kImageCount; i++) {
        // 计算imageView的x值
        // ****** imageView的x值 +5,将每张图片向后平移5个点;
        // ****** 测试结果:分页效果是不根据子View(图片)来分页,而是根据ScrollView的宽度;
        CGFloat imageViewX = i * (scrollViewSize.width +5);
        
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(imageViewX, 0, scrollViewSize.width, scrollViewSize.height)];
        
        // 设置图片
//        imageView.image =[UIImage imageNamed:@"img_01"];
        // 拼接图片的名称
        NSString *imageName = [NSString stringWithFormat:@"img_%02d",i + 1];
        
        imageView.image = [UIImage imageNamed:imageName];
        
        // 添加到scrollView
        [_scrollView addSubview:imageView];
    }
    
    // 设置 scrollView的contentSize
    _scrollView.contentSize = CGSizeMake(kImageCount * scrollViewSize.width, 0);
    
    // ****** 设置边距 ,测试结果表明分页会忽略边距;
    _scrollView.contentInset = UIEdgeInsetsMake(10, 50, 10, 50);
    
    // scrollView的分页效果 (根据scrollView的宽度进行分页的)
    _scrollView.pagingEnabled = YES;

ScrollView的滚动, 可以通过setContentOffset:animated:方法来实现;

// offset: 最终要显示的位置
// animated: 是否显示滚动过程
[_scrollView setContentOffset:offset animated:YES];

UIPageControl

UIPageControl 显示一个横向的点, 用于指示作用, 可以与ScrollView配合使用;

属性 作用
numberOfPages 一共需要显示多少点
currentPage 当前的点, 可以通过该属性直接设置当前选中点的
pageIndicatorTintColor 非选中点的颜色
currentPageIndicatorTintColor 选中点的颜色
点击事件相关

UIPageControl 继承至UIControl, 因此可以添加一个点击事件监听;经测试监听的时间为UIControlEventValueChanged;

[_pageControl addTarget:self action:@selector(pgct:) forControlEvents:UIControlEventValueChanged];

控件点击后会根据点击位置与当前位置的差值确定对currentPage的加减;

重要

defersCurrentPageDisplay ,一个BOOL值, 用于延迟currentPage对空间的显示, 当设置为YES的时候, 点击空间currentPage值依旧会变化,但是不会反应到界面上;需要显示调用[_pageControl updateCurrentPageDisplay];方法;

- (IBAction)pgct:(id)sender {
    // 当defersCurrentPageDisplay == YES的时候, currentPage依旧增减, 但是界面不会变化;
    NSLog(@"__%s__, %ld", __func__, _pageControl.currentPage);
    
    // 显示调用如下方法,更新界面;
    [_pageControl updateCurrentPageDisplay];
}

defersCurrentPageDisplay不适用于直接设置currentPage的值, 直接设置依旧会更新界面;

NSTimer

NSTimer继承至NSObject, 用于设置一个定时器,可以设置重复执行,预约执行,触发和取消执行;
可以通过如下三种方式构建一个NSTimer对象:

  1. + scheduledTimerWithTimeInterval系列方法, 初始化一个NSTimer 对象,并将该对象放入当前loop中;
  2. + timerWithTimeInterval 系列方法, 仅创建一个对象;
  3. - initWithFireDate:interval:target:selector:userInfo:repeats:方法, 初始化一个alloc 的方法;
方法 描述
+ scheduledTimerWithTimeInterval:invocation:repeats: 根据invocation 指定具体的执行任务
+ scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: 根据target和selector指定具体执行任务
+ timerWithTimeInterval:invocation:repeats: 同上, 不放入默认run loop
+ timerWithTimeInterval:target:selector:userInfo:repeats: ---
- initWithFireDate:interval:target:selector:userInfo:repeats: alloc init实现初始化
+ timerWithTimeInterval:repeats:block: ---
+ scheduledTimerWithTimeInterval:repeats:block: ---
- fire 触发任务执行
- invalidate 从任务队列中移除
属性 描述
valid 一个BOOL值, 用来判断当前timer是否有效
fireDate 触发时间
timeInterval 触发间隔
userInfo 构建对象时传入的数据

NSRunLoop

NSRunLoop 用于处理出入请求, 系统提醒 NSPort对象, NSConnection对象 和 NSTimer事件; 我们可以理解NSRunLoop是一个无线循环, 会不停的循环执行并检查自己的输入源中是否有待执行的事件;

NSRunLoop 不能被应用主动创建或管理, 可以通过NSRunLoop的类方法获取当前线程的loop对象[NSRunLoop currentRunLoop];, 和主线程loop对象[NSRunLoop mainRunLoop];

NSRunLoop 的运行模式, loop内部有不同的运行模式, 不同的输入源运行在不同的模式上!

未完待续...

参考

NSRunLoop 概述和原理

未完待续...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,036评论 29 470
  • 来自网络 序言 目前形势,参加到iOS队伍的人是越来越多,甚至已经到供过于求了。今年,找过工作人可能会更深刻地体会...
    用心在飞阅读 795评论 5 4
  • 转自 iOS 面试常见问题最全梳理 序言 目前形势,参加到iOS队伍的人是越来越多,甚至已经到供过于求了。今年,找...
    ZMJun阅读 775评论 0 11
  • 序言 目前形势,参加到iOS队伍的人是越来越多,甚至已经到供过于求了。今年,找过工作人可能会更深刻地体会到今年的就...
    Jack_lin阅读 78,072评论 110 1,944
  • 今天携子携老去了大明湖,真心全是人啊,不过十一嘛,很正常,感受了一下大明湖畔的风景,莫名的总想重现还珠格格中的桥段...
    金金归来阅读 468评论 0 0