1.对MVVM设计模式的理解,
/// 微博首页列表视图模型。(体会视图模型的用法,就是一个处理器,讲复杂的数据处理逻辑,放在这个处理器中处理,处理完成后通过回调通知视图控制器展示UI。一般无特殊情况,有下列几个任务。)
/*4个任务
1.负责微博的数据处理(将json数据处理成Model)
2.封装上拉下拉逻辑(在内部定义数据源,page 之类的参数,实现表格的刷新数据请求,请求调用的是其他类的方法)
3.
*/
2.对代码框架的理解
//体会代码框架
/*
1.界面(视图和视图控制器,负责UI界面的显示逻辑)
2.网络 (项目中使用两层封装,第一层封装AFN的get和post请求,使其在一处处理便于修改和维护。第二层对工程具体url的数据请求封装,其中包括对参数的处理,对结果json的处理)
3.数据模型(数据储存,和数据变形处理,包括计算高度等)
4.视图模型(视图控制器中的数据处理,包括字典转模型等)
*/
3.对项目框架的理解
//项目框架
/*
1.设计(包括美化和切图)
2.网络 (数据请求,tcp/ip http 请求,数据上传)
3.界面 (uikit,fountion,player,animation)
4.数据处理(算法,数据结构)
5.appstore相关(打包,上架,证书,内购,推送)
*/
UIViewController 的子类视图控制器 和 界面间的切换
//1.添加
//addChildViewController将viewController加入到self的childViewControllers数组里面。
[self addChildViewController:viewController];
//将viewController的view定制frame之后加入到self.view上。
viewController.view.frame = self.view.bounds;
[self.view addSubview:viewController.view];
//将self作为参数发送消息给viewController。子控制器的添加结束,生命周期将会正常随父控制器调用。
[viewController didMoveToParentViewController:self];
//2.移除
//发送消息给self(child controller),将要从parent controller上移除。参数必须是nil
[self willMoveToParentViewController:nil];
//移除view
[self.view removeFromSuperview];
//从parent controller的childControllers数组中移除
[self removeFromParentViewController];
//3.切换
[fromViewController willMoveToParentViewController:nil];
[self addChildViewController:toViewController];
__weak typeof(self) weakSelf = self;
[self transitionFromViewController:fromViewController
toViewController:toViewController
duration:duration
options:options
animations:animations
completion:^(BOOL finished)
{
[fromViewController removeFromParentViewController];
[toViewController didMoveToParentViewController:weakSelf];
if (completion) {
completion(finished);
}
}];
1.webView和js的交互方法
/// WebView的注入,直接通过js修改 “本地浏览器中” 缓存页面的内容
@objc private func autoFill() {
//准备js
let js = "document.getElementById('userId').value = '13001021648';"+"document.getElementById('passwd').value = 'sj13001021648';"
//让webview执行js
webView.stringByEvaluatingJavaScript(from: js)
}
2.AFN的errorcode 200 的处理方式(不支持的json解析类型)
//其为一个闭包,其实就是特殊的懒加载,懒加载得到的是可变对象,这个得到的是个静态全局对象。所以当我们需要对单例对象特殊初始化时,可以在闭包中进行初始化(推导,懒加载也可以这么做,这就nice了)
/// 网络单例实例对象
static let shared:WBNetworkManager = {
//实例化一个对象
let instance = WBNetworkManager()
//添加响应序列化的数据类型
instance.responseSerializer.acceptableContentTypes?.insert("text/plain")
return instance
}()
3.字符串和子串
//>3.从query字符串中取出授权码'
let fromIndex = "code=".endIndex
let code = String.init((request.url?.query![fromIndex...])!)
print("获取授权码\(code)”)
通过下标代替原来的方法 fromIndex,toIndex 和 range,得到的是一个subString。
下面一些字符串和子串的操作。
//子串SubString是string的一个片段,与原始字符串共享存储。可以避免和延迟原始字符串的内容复制。
//避免了不需要的内存复制。
var str = "Hello, playground"
do {
//取子串,并转化成字符串
//>1.取前一段,toIndex
let rowData = "Hi there!It's nice to meet you!"
let endIndex = rowData.index(of: "!")
let subString0 = rowData[...endIndex!]
print(subString0)
//>2.取后一段,fromIndex
let fromIndex = rowData.index(after: endIndex!)
let subString1 = rowData[fromIndex...]
print(subString1)
//>3.range
let subString2 = rowData[endIndex!...fromIndex]
print(subString2)
}
do {
//对子串SubString进行操作,提供和String一样的接口
let rowData = "Hi there!It's nice to meet you!"
let endIndex = rowData.index(of: "!")
let subString0 = rowData[...endIndex!]
print("\(subString0) is \(subString0.count) characters long.")//取长度
let shoutingSentence = subString0.uppercased()//大写变化
print(shoutingSentence)
}
do {
//subString to String
let rawInput = "126 a.b 22219 zzzzzz"
let numbericPrefix = rawInput.prefix(while: {"0"..."9" ~= $0})
print(numbericPrefix)
let string = String(numbericPrefix)
print(string)
}
do {
//string 转 Int
let rawInput = "126 a.b 22219 zzzzzz"
let numbericPrefix = rawInput.prefix(while: {"0"..."9" ~= $0})
let prefix = Int(String(numbericPrefix),radix:10)
print(prefix)
}
//注意:substring 会对原始字符串 进行引用。一般作为中间变量操作,一般不需要存储。