wait、notify学习小记。
一个不是太合适的场景:顾客等饭吃、厨子做饭、厨子做好饭并停止做饭、顾客吃饭、顾客吃完饭接着等饭吃、厨子接着做饭………1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
final Object lock = new Object();
Thread customerThread = new Thread(new Runnable() {
public void run() {
synchronized (lock) {
try {
lock.wait();
} catch (Exception ex) {
}
}
while (true) {
synchronized (lock) {
try {
System.out.println("顾客吃完了,厨师可以继续做饭..............");
lock.notify();
lock.wait();
} catch (Exception ex) {
}
}
}
}
});
Thread cookThread = new Thread(new Runnable() {
public void run() {
while (true) {
synchronized (lock) {
System.out.println("厨师做好了,顾客可以吃了,暂停做饭");
lock.notify();
try {
lock.wait();
} catch (Exception ex) {
}
}
}
}
});
customerThread.start();
cookThread.start();
reloadData导致cell错乱
Providing a nonnegative estimate of the height of rows can improve the performance of loading the table view. If the table contains variable height rows, it might be expensive to calculate all their heights when the table loads. Estimation allows you to defer some of the cost of geometry calculation from load time to scrolling time.
The default value is automaticDimension, which means that the table view selects an estimated height to use on your behalf. Setting the value to 0 disables estimated heights, which causes the table view to request the actual height for each cell. If your table uses self-sizing cells, the value of this property must not be 0.
When using height estimates, the table view actively manages the contentOffset and contentSize properties inherited from its scroll view. Do not attempt to read or modify those properties directly.
URLSession
距离51小长假还有不到4个小时,干等也是等,不如湿等吧- - -过一遍URLSession的API,平日里也是习惯了使用AFNetworking、Alamofire完成数据请求,很少有需要去看这些系统的东西了。
URLSession提供了三种构造方式,分别是单利方式、携带配置信息、携带代理对象和任务队列:1
2
3open class var shared: URLSession { get }
public /*not inherited*/ init(configuration: URLSessionConfiguration)
public /*not inherited*/ init(configuration: URLSessionConfiguration, delegate: URLSessionDelegate?, delegateQueue queue: OperationQueue?)
URLSessionConfiguration用于管理session的行为和策略,比如超时时间、缓冲策略、是否允许蜂窝数据请求等等,有如下三种类型:1
2
3
4
5
6// 默认
open class var `default`: URLSessionConfiguration { get }
// 和.default类似,但是缓存、cookie、凭据无法使用了,无法存到磁盘中
open class var ephemeral: URLSessionConfiguration { get }
// 后台session, 典型的后台下载任务
open class func background(withIdentifier identifier: String) -> URLSessionConfiguration
sessionObj.configuration属性是只读的,所以设置session配置信息只能在构造session的时候,之后便不可可变这些配置信息,如果要改变,那也只能是在另外创建一个session了。通过sessionObj.share方式使session是没有配置信息的。
在构造会话的时候传入一个URLSessionDataDelegate对象,这样就可以获取会话进行的状态,同样sessionObj.delegate是只读的,只能在构造会话的时候设置。
开启会话之后,便可以绑定会话任务URLSessionTask,通过调用不同的API创建不同类型的任务,如下四种:1
2
3
4
5
6
7
8// 将请求的数据存到内存中 sessionObj.dataTask(with:)
open class URLSessionDataTask : URLSessionTask {}
// 上传任务 URLSessionDataTask的子类 sessionObj.dataTask.uploadTask(with:from:)
open class URLSessionUploadTask : URLSessionDataTask {}
// 下载任务
open class URLSessionDownloadTask : URLSessionTask {}
// 流任务,和指定主机端口或者服务器建立tcp/ip连接,streamTask(withHostName:port:) or streamTask(with:)
open class URLSessionStreamTask : URLSessionTask {}
URLSessionDataTask类型的任务会将
任务创建之后便可以通过sessionObj.resume()开启任务,任务中的所有属性都是可以通过kvo来监听状态改变的,当我们发起一个一般的请求任务或者下载任务的时候,可以监听countOfBytesReceived来获取已经请求到数据的长度1
2
3task.addObserver(self, forKeyPath: "countOfBytesReceived",
options: .new,
context: nil)
会话任务提供了两种
URLSessionDataTask
A URL session task that returns downloaded data directly to the app in memory.
会直接把下载的数据到数据存在内容中,写demo的时候下载了一个800多M的文件,直接触发了内存警告,所以慎用它访问稍大的文件
轻轻考医学审核被拒总结
苹果虐我千百遍,我待苹果如初恋
虽说苹果审核相对安卓而言严格一些、条条框框多一些,但是其实入行到现在,经手的APP说多不多说少不少也有几个了,审核经历都还是蛮顺利的,即使偶尔被拒,也能很清晰的知道问题出现在什么地方。但是两个月前换工作之后,接手目前公司的APP,1.0版本的提交审核经历真滴是让我吐了,历经了一个半月,被拒了十几次,一个半月的工作状态就是当日提交审核、次日被拒、被拒当天再次提审、再次日接着被拒,如此循环,几乎让我打算打退堂鼓了。
Laravel零散小记
- blade渲染取限定长度字符:
{ {str_limit($post->content, 20, '.....')} }
- blade渲染出html效果(默认是把源数据以纯文本的形式展示):
{!! str_limit($post->content, 20, '.......') !!}
- form的提交方式是只有get、post,但是Laravel还可以使用put patch delete,如果要使用这三种方式,需在form中注明该方式
<input type="hidden" name="_method" value="PUT(patch、delete)">
融云IM
–IM在现在的APP中已是很普通常见的功能了,而我最后使用IM功能已是两年半之前的一个APP,时间很久,各个IM厂商的SDK更新很大,所以趁着手里比较闲,抽了两天时间过了一下IM的实现。我是以融云SDK为入手点,完整的过了一下它的开发文档,最终形成一个具有好友系统的聊天demo,这边笔记是用来记录官方文档中比较重要的点和完成demo过程中想到的一些内容。
融云SDK的消息推送机制
如果APP保持和融云服务器的长连接(在线),则融云服务器会直接把消息推送给APP,APP再把消息内容以本地推送的形式展示出来(需要确定是如果是前台会发推送吗),流程图如下:
如果APP和融云服务器没有保持长连接(离线),则融云服务器会把消息推送给APNs,再由APNs将消息推送给手机,流程图如下如下:
注:应用切换至后台 2 分钟后,将自动切断与服务器的连接,此时应用为离线状态,新消息将会以 Push 方式推送。 用户在线状态下,应用在前台显示时,不会收到消息通知。
token
融云并不负责维护好友关系,也不需要这些数据,所以完成IM,APP的服务器至少需要完成两个工作是:维护好友关系和请求RCtoken
APP服务器和融云服务器的RCtoken交换机制:用户通过APP的账号密码登录APP服务器,APP服务器再向融云服务器请求该用户的RCtoken,并将RCtoken下发至APP,APP携带次RCtoken进行通信。
demo(好友体系、头像自己存储)
错误:
- 不要用同一个token多次connect, sdk会自动做好重连工作!!!
- 用户信息提供者为空请检查是否设置 [RCIM sharedRCIM].userInfoDataSource ,并且保证设置的对象没有被释放 [RCIM sharedRCIM].userInfoDataSource 是 weak 属性
- 自定义聊天页面的时候,创建该页面的时候,直接设置回话类型,如果在viewdidload中进行设置,会出现再次进入该页面聊天记录不显示的现象。(考虑会话列表也是)
使用自带的聊天界面:
弹出的键盘包含了:1. 语音功能、2 loc 功能、 3. 发送本地图片功能、4、图片保存功能,5使用相机功能,
所有要完成如下操作:1. 导入语音的sdk 2. loc 授权,3. 图片使用授权 4. 保存图片授权、5相机授权,否则使用到以上的任意一个功能点都会导致崩溃,或者屏蔽这些功能,看截图