保存工作和学习过程中使用,学习到的Demo

原文:保存工作和学习过程中使用,学习到的Demo

iOS_Demo保存工作和学习过程中使用,学习到的Demo

[1]. block_pass_value使用block作为方法的参数,实现界面反向传值。[2]. multi_image_cache_and_download使用NSBlockOperation和NSCache,实现tableViewcell里加载网络图片,并带有缓存功能(仿照SDWebImage的逻辑)。

[3]. init_and_initWithFrame对于UIView,即使是用init方法创建实例,也会先调用initWithFrame:方法,然后再调用init方法。

[4]. clean_tableview将tableview的datasource单独抽取出来作为一个类,减少viewcontroller的代码量。cell的绘制方法使用block函数调用。

[5]. associate_object在分类中使用关联对象给类添加属性。

[6]. collectionview_masonry_layout瀑布流的实现,自定义cell的垂直,水平间距,以及列数。

- (void)viewDidLoad {      

  [super viewDidLoad];      

  [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:CellIdentifier];  

  SSJMasonryLayout *layout = (SSJMasonryLayout*)self.collectionView.collectionViewLayout;    layout.delegate = self;   

 //自定义列数,cell的水平距离,cell的垂直距离   

 layout.numberOfColumns = 4;   

 layout.itemHorizontalSpacing = 10;   

 layout.itemVerticalSpacing = 20;

}

#pragma mark- SSJMasonryLayoutDeleagte

- (CGFloat) collectionView:(UICollectionView*) collectionView  layout:(SSJMasonryLayout*) layout  heightForItemAtIndexPath:(NSIndexPath*) indexPath {    

//提供cell的随机高度    

CGFloat randomHeight = 100 + (arc4random() % 140);    

return randomHeight;

}

[7]. oc_js_interactionOC与JS代码的简单交互。

 [8]. access_private_property用KVC和runtime改变私有属性。

1. 定义公有属性和私有属性:

@interface Person : NSObject@property (nonatomic, copy) NSString *name;

//公共属性

@end

@interface Person()

@property (nonatomic, copy) NSString *job;

//私有属性

@end

@implementation Person{    

NSString *_country;//私有成员变量

}

2. 使用kvc修改公共属性和私有属性以及私有成员变量

[person setValue:@"jack" forKey:@"name"];

//公共属性

[person setValue:@"coder" forKey:@"job"];

//私有属性

[person setValue:@"China" forKey:@"country"];

//私有成员变量

NSLog(@"kvc改变成员变量的值:%@",person);

//name:jack, job:coder, country:China####

3. 使用runtime修改私有属性以及私有成员变量

[self changeIvarOfObject:person withIvarName:@"_job" toValue:@"manager"];

[self changeIvarOfObject:person withIvarName:@"_country" toValue:@"America"];

NSLog(@"runtime 改变成员变量的值:%@",person);

//name:Bob, job:manager, country:America

- (void)changeIvarOfObject:(id)object withIvarName:(NSString *)name toValue:(NSString *)value{    

Ivar ivar = class_getInstanceVariable([object class], [name UTF8String]);        object_setIvar(object, ivar, value);

}

[9]. custom_segue自定义转场动画:

将push显示为model:新建一个类继承UIStoryboardSegue,然后重写perform方法。

#import "CustomSegue.h"

@implementation CustomSegue

- (void)perform{    

UIViewController *fromVC = (UIViewController *)self.sourceViewController;    UIViewController *toVC = (UIViewController*)self.destinationViewController;

        //获取第一个页面初始状态的frame    

CGRect f = fromVC.view.frame;    

CGRect originalSourceRect = fromVC.view.frame;       

 f.origin.y = f.size.height;        

 //令第二个页面在开始的时候位于屏幕底部    

 toVC.view.frame = f;    

 toVC.view.alpha = 0.0f;    

[[fromVC.view superview] addSubview:toVC.view];       

 [UIView animateWithDuration:0.3 animations:^{                

//令第二个页面的frame等于第一个页面初始状态的frame(满屏)       

 toVC.view.frame = originalSourceRect;        

toVC.view.alpha = 1.0f;           

 } completion:^(BOOL finished) {               

 [toVC.view removeFromSuperview];        

 fromVC.view.alpha = 1.0f;       

 [fromVC.navigationController pushViewController:toVC animated:NO];           

 }];}

[10]. mvvm_kvo_two_way_binding用FBKVOController实现的mvvm的双向绑定。

viewmodel监听model的变化:

//模拟网络请求   

 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{                

//新请求下来一个model        

self.model = [[SJModel alloc] init];        

self.model.number = arc4random() % 100;;                

//viewmodel监听model的改变      

  [self.KVOController observe:self.model keyPath:@"number" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial block:^(id  _Nullable observer, id  _Nonnull object, NSDictionary* _Nonnull change) {            NSLog(@"viewmodel监听到了model的改变后,立即改变自己被控制器监听的属性");            self.contentStr = [self convertNumber:self.model.number];

 }];    

});

view监听viewmodel的变化:

- (instancetype)initWithViewModel:(SJViewModel *)viewModel{    

self = [super init];        

if (self) {                

self.viewModel = viewModel;                

//view监听viewmodel的contentStr属性的改变,一旦改变,刷新自己       

 [self.KVOController observe:self.viewModel keyPath:@"contentStr" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial block:^(id  _Nullable observer, id  _Nonnull object, NSDictionary* _Nonnull change) {            

NSLog(@"当view监听到了viewmodel的改变后,立即改变自己"); 

self.label.text = self.viewModel.contentStr;        

}]; }   

 return self;}

[11]. multi_thread_communication线程通信的几个例子:NSOperation,GCD,NSObject

[12]. gcd_demo介绍了GCD的API:dispatch_barrier,dispatch_wait,dispatch_group,dispatch_apply等

[13]. autoresizing_demo由xib生成的view默认会跟随父控件大小的变化而变化。如果不让二者有依赖性,需要设置view的autoresizingMask属性。

UIView *subview = [[NSBundle mainBundle] loadNibNamed:@"subview" owner:nil options:nil].firstObject;   

 //不让xib的view随着父控件的大小而变化subview.autoresizingMask = UIViewAutoresizingNone;

[14].block_lowlevel_analysisblock的底层分析

[15].method_swizzling使用runtime交换方法(类方法,实例方法)交换类方法

+ (void)load {        

static dispatch_once_t onceToken;   

 dispatch_once(&onceToken, ^{                

SEL originalSelector = @selector(imageNamed:);        

SEL swizzledSelector = @selector(sj_imageNamed:);                

Method originalMethod = class_getClassMethod(self, originalSelector);        

Method swizzledMethod = class_getClassMethod(self, swizzledSelector);               

 //交换实现       

 method_exchangeImplementations(originalMethod, swizzledMethod);    });}

+ (UIImage *)sj_imageNamed:(NSString *)name{

    UIImage *image = [UIImage sj_imageNamed:name];

        if (image) {

        NSLog(@"图片加载成功");

    } else {

        NSLog(@"图片加载失败");

    }        

return image;}

交换实例方法:

+ (void)load { 

       static dispatch_once_t onceToken; 

       dispatch_once(&onceToken, ^{ 

               Class class = [self class];

                SEL originalSelector = @selector(viewWillAppear:);

                SEL swizzledSelector = @selector(sj_viewWillAppear:);                

Method originalMethod = class_getInstanceMethod(class, originalSelector); 

Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);                

//交换实现       

 method_exchangeImplementations(originalMethod, swizzledMethod);

    });

}

- (void)sj_viewWillAppear:(BOOL)animated {

    [self sj_viewWillAppear:animated];

    NSLog(@"viewWillAppear: %@", self);

}

[16]. kvo_array_count使用runtime交换方法来同志array count是否变化(未完成)

[17]. class_addMethod_demo给类添加方法:避免在运行时收到某个没有实现的方法。

#import "Car+Fly.h"

#import

void beginToFly(id self, SEL _cmd) {

NSLog(@"begin to fly");

}

@implementation Car (Fly)

+ (BOOL)resolveInstanceMethod:(SEL)sel {

//如果是fly方法,目前没有这个方法的实现,于是就添加一个fly方法

if (sel == @selector(fly)) {

class_addMethod([self class], sel, (IMP)beginToFly, "v@:");

return YES;

}

return [super resolveInstanceMethod:sel];

}

@end

[18]. kvc_demo

使用kvc访问共有属性,私有属性,keypath,集合操作等。

//set public ivar

[person setValue:@"Peter" forKey:@"name"];

NSLog(@"name:%@",person.name);

//set public _ivar

[person setValue:@"male" forKey:@"_sex"];

NSLog(@"sex:%@",[person valueForKey:@"_sex"]);

//set privacy ivar

[person setValue:@"centry road" forKey:@"address"];

NSLog(@"address: %@",[person valueForKey:@"address"]);

//set privacy _ivar

[person setValue:@"China" forKey:@"_country"];

NSLog(@"country: %@",[person valueForKey:@"_country"]);

//set primary type

[person setValue:[NSNumber numberWithInteger:12] forKey:@"money"];

NSLog(@"set money: %ld",person.money);

NSLog(@"query money: %@",[person valueForKey:@"money"]);

//set keypath

[person setValue:@"Apple" forKeyPath:@"company.name"];

NSLog(@"name of company: %@",[person valueForKeyPath:@"company.name"]);

//collection

person.friends = @[@"Jim",@"Brunce",@"Nancy"];

NSNumber *count = [person valueForKeyPath: @"friends.@count"];

NSLog(@"number of friend: %ld", [count integerValue]);

//start from person

NSNumber *avg = [person valueForKeyPath: @"[email protected]"];

NSLog(@"avg of products: %ld", [avg integerValue]);

NSNumber *max = [person valueForKeyPath: @"[email protected]"];

NSLog(@"max of products: %ld", [max integerValue]);

NSNumber *min = [person valueForKeyPath: @"[email protected]"];

NSLog(@"min of products: %ld", [min integerValue]);

NSNumber *sum = [person valueForKeyPath: @"[email protected]"];

NSLog(@"sum of products: %ld", [sum integerValue]);

[19]. bad_access_demo

访问野指针

你可能感兴趣的:(保存工作和学习过程中使用,学习到的Demo)