一、block
1️⃣、简介
2️⃣、一个简单的block
3️⃣、结合tepydef使用,作为属性实现传值
4️⃣、内存管理
二、代理
1️⃣、简介
2️⃣、基本使用:协议定义,代理方遵守协议,委托方判断代理方是否实现协议方法
3️⃣、实现多继承
4️⃣、控制器瘦身
5️⃣、内存管理
三、NSThread
1️⃣、简介
2️⃣、线程创建:静态,动态,隐式
3️⃣、线程通信:主线程执行、当前线程执行、指定线程执行
4️⃣、线程同步:NSLock、NSCondition、@synchronized
四、NSOperation
1️⃣、简介:NSOperation是一个抽象基类,因此如果想要使用NSOperation,需要使用到其两个子类NSinvocationOperation、NSBlockOperation,或者自定义Operation;
2️⃣、NSinvocationOperation:创建
3️⃣、NSBlockOperation:创建、添加操作
4️⃣、自定义NSOperation:需要正确的取消操作
5️⃣、线程控制:取消、开始、监听、添加依赖关系和优先级
6️⃣、结合NSOperationQueue使用:暂停和继续
五、GCD
1️⃣、队列和操作
2️⃣、串行队列、并行队列:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),dispatch_get_main_queue(),dispatch_queue_create("xiaozhu", DISPATCH_QUEUE_SERIAL,dispatch_queue_create("......", DISPATCH_QUEUE_CONCURRENT);
3️⃣、同步和异步
4️⃣、死锁
NSLog(@"1"); // 任务1 dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"2"); // 任务2 }); NSLog(@"3"); // 任务3
5️⃣、新方式创建单例
+ (AccountManager *)sharedManager { static AccountManager *sharedAccountManagerInstance = nil; static dispatch_once_t predicate; dispatch_once(&predicate, ^{ sharedAccountManagerInstance = [[self alloc] init]; }); return sharedAccountManagerInstance; }
六、Webkit
1️⃣、四种交互方式:WKUIDelegate,WKUserScript注入、WKScriptMessageHandler,- (void)evaluateJavaScript: completionHandler:
2️⃣、JS调用本地方法:- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
//插入html getElementsByTagName 根据html自带标签定位元素 - (IBAction)insertHtmTouched:(id)sender { //插入整个页面内容 // document.getElementsByTagName('body')[0];" //替换第一个P元素内容 NSString *tempString = [NSString stringWithFormat:@"document.getElementsByTagName('p')[0].innerHTML ='%@';",self.someString]; [self.myWebView evaluateJavaScript:tempString completionHandler:^(id item, NSError * _Nullable error) { }]; }
七、UIWebVIew
1️⃣、JS调用本地方法:- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
2️⃣、本地调用JS:- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
// 插入html 根据getElementById 定位元素 - (IBAction)insertDivHtml:(id)sender { //替换第id为idtest的DIV元素内容 NSString *tempString2 = [NSString stringWithFormat:@"document.getElementById('idTest').innerHTML ='%@';",self.someString]; [self.myWeb stringByEvaluatingJavaScriptFromString:tempString2];
八、项目架构
九、UITableViewCell上有个UILabel,显示NSTimer实现的秒表时间,手指滚动cell过程中,label是否刷新,为什么?
这是否刷新取决于timer加入到Run Loop中的Mode是什么。Mode主要是用来指定事件在运行循环中的优先级的,分为:
- NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默认,空闲状态
- UITrackingRunLoopMode:ScrollView滑动时会切换到该Mode
- UIInitializationRunLoopMode:run loop启动时,会切换到该mode
- NSRunLoopCommonModes(kCFRunLoopCommonModes):Mode集合
苹果公开提供的Mode有两个
- NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
- NSRunLoopCommonModes(kCFRunLoopCommonModes)
如果我们把一个NSTimer对象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主运行循环中的时候, ScrollView滚动过程中会因为mode的切换,而导致NSTimer将不再被调度。当我们滚动的时候,也希望不调度,那就应该使用默认模式。但是,如果希望在滚动时,定时器也要回调,那就应该使用common mode。
对于这道题,如果要cell滚动过程中定时器正常回调,UI正常刷新,那么要将timer放入到CommonModes下,因为是NSDefaultRunLoopMode,只有在空闲状态下才会回调。
NSTimer传送门
十、UIBezeirPath、CAShapLayer
说到CAShapLayer就不得不说到UIBezierPath: UIBezierPath是在 UIKit 中的一个类,继承于NSObject,可以创建基于矢量的路径。使用此类可以定义常见的圆形、多边形等形状 。我们使用直线、弧(arc)来创建复杂的曲线形状。每一个直线段或者曲线段的结束的地方是下一个的开始的地方。每一个连接的直线或者曲线段的集合成为subpath。一个UIBezierPath对象定义一个完整的路径包括一个或者多个subpaths。
CAShapeLayer: CAShapeLayer顾名思义,继承于CALayer。 每个CAShapeLayer对象都代表着将要被渲染到屏幕上的一个任意的形状(shape)。具体的形状由其path(类型为CGPathRef)属性指定。 普通的CALayer是矩形,所以需要frame属性。CAShapeLayer初始化时也需要指定frame值,但 它本身没有形状,它的形状来源于其属性path 。CAShapeLayer有不同于CALayer的属性,它从CALayer继承而来的属性在绘制时是不起作用的。
步骤:
1、新建UIBezierPath对象bezierPath
2、新建CAShapeLayer对象caShapeLayer
3、将bezierPath的CGPath赋值给caShapeLayer的path,即caShapeLayer.path = bezierPath.CGPath
4、把caShapeLayer添加到某个显示该图形的layer中
UIBezierPath * path = [[UIBezierPath alloc]init]; [path addArcWithCenter:CGPointMake(self.view.center.x, 175) radius:25 startAngle:0 endAngle:2*M_PIclockwise:NO(如果不是一个闭合的圆,显示顺时针部分还是逆时针的部分)]; 画圆 [path moveToPoint:CGPointMake(self.view.center.x, 200)]; 画笔移到某个点 [path addLineToPoint:CGPointMake(self.view.center.x, 250)]; 划直线 self.layer1 = [CAShapeLayer layer]; self.layer1.path = path.CGPath; self.layer1.lineWidth = 10; self.layer1.fillColor = [UIColor clearColor].CGColor; self.layer1.strokeColor = [UIColor blackColor].CGColor; self.layer1.lineCap = kCALineCapRound; [self.view.layer addSublayer:self.layer1];
十一、上线问题
十二、CALayer和UIView
1、在说CALayer和UIView有什么不同时,首先说明其关系。
2、当创建一个UIView对象时,其内部会自动创建一个层(CALayer对象),通过UIView的layer属性,可以访问到这个层。当UIView需要显示的屏幕上时,会调用其drawRect:方法进行绘制,并且将所有的内容绘制到这个层上。绘图完毕后,再将其拷贝到屏幕上,完成UIView的显示。换句话说,UIView不具备显示的功能,其内部的层才具备显示功能。
3、UIVIew继承自UIResponder,而CALayer继承自NSObject。
4、改变CALayer的一些属性,比如corners、position、opacity等,会产生隐式动画,而UIView不会。
5、UIView可以响应触摸事件,而CALayer不会。
6、UIView侧重于内容的管理,CALayer侧重于内容的绘制。