网站seo批量查询工具,wordpress 文章自动分页,东营市建设工程管理信息网,免费聊天不充值软件文章目录 1. iOS应用生命周期1.1 应用程序的架构1.2 iOS应用的5种状态#xff1a;1.2.1做一些操作对应的生命周期调用的顺序1.2.2全面的生命周期执行流程图 1.3 Main函数入口1.4 几个关键对象1.5 Main Run Loop 2. UI界面2.1 UIWindow2.2 UIViewController生命周期*2.2.1 View… 文章目录 1. iOS应用生命周期1.1 应用程序的架构1.2 iOS应用的5种状态1.2.1做一些操作对应的生命周期调用的顺序1.2.2全面的生命周期执行流程图 1.3 Main函数入口1.4 几个关键对象1.5 Main Run Loop 2. UI界面2.1 UIWindow2.2 UIViewController生命周期*2.2.1 View的加载过程2.2.2 controller中创建view2.2.3 ViewController生命周期 2.3 navigation controller2.4 WKWebView2.5 页面传值2.5.1 函数传值2.5.2 delegate传值 3. APP之间跳转方式3.1 URL Scheme方式3.2 niversal Links方式 1. iOS应用生命周期
作为应用程序的委托对象AppDelegate类在应用生命周期的不同阶段会回调不同的方法。
1.1 应用程序的架构
iOS应用程序都遵循Model-View-Controller的架构Model负责存储数据和处理业务逻辑View负责显示数据和与用户交互Controller是两者的中介协调Model和View相互协作。它们的通讯规则如下
Controller能够访问Model和ViewModel和View不能互相访问当View与用户交互产生事件时使用target-action方式来处理当View需要处理一些特殊UI逻辑或获取数据源时通过delegate或data source方式交给Controller来处理Model不能直接与Controller通信当Model有数据更新时可以通过Notification或KVO (Key Value Observing)来通知Controller更新View 1.2 iOS应用的5种状态
Not Running非运行状态应用没有运行或被系统终止运行 Inactive前台非活跃状态应用正式进入前台状态但是还没有接受事件处理 Active前台活跃状态应用进入前台状态能接受事件并且进行处理 Background后台状态应用进入后台之后依然能够执行代码。如果有可以执行的代码就会执行如果没有可执行的代码或者将可执行的代码执行完毕应用会马上进入挂起状态 Suspended挂起状态被挂起的应用进入一种“休眠”状态不能执行任何代码。当手机系统内存不足时应用会被终止。 在应用状态有变化的过程中iOS系统会调用AppDelegate中的一些方法并且发送一些通知。下面汇总了一部分主要的方法和和通知。
//应用启动并进行初始化时会调用该方法并发出通知。这个阶段会实例化跟试图控制器。
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
//本地通知UIApplicationDidFinishLaunchingNotification//应用进入前台并处于活跃状态时调用该方法并发出通知。这个阶段可以恢复UI的状态。
- (void)applicationDidBecomeActive:(UIApplication*)application
//本地通知UIApplicationDidBecomeActiveNotification//应用从活跃状态进入到非活跃状态时调用该方法并发出通知。这个阶段可以保存UI的状态。
- (void)applicationWillResignActive:(UIApplication*)application
//本地通知UIApplicationWillResignActiveNotification//应用进入后台是调用该方法并发送通知。这个阶段可以保存用户数据释放一些数据库资源等。
- (void)applicationDidEnterBackground:(UIApplication*)application
//本地通知UIApplicationDidEnterBackgroundNotification//应用进入到前台但是还没有处于活跃状态是调用该方法并发出通知。这个阶段可以恢复用户数据。
- (void)applicationWillEnterForeground:(UIApplication*)application
//本地通知UIApplicationWillEnterForegroundNotification//应用被终止时调用该方法并发出通知内存清除时除外。这个阶段会释放一些资源也可以保存用户数据。
- (void)applicationWillTerminate:(UIApplication*)application
//本地通知UIApplicationWillTerminateNotification1.2.1做一些操作对应的生命周期调用的顺序 1、程序启动状态由Not running - Inactive - Active willFinishLaunchingWithOptions didFinishLaunchingWithOptions applicationDidBecomeActive 2、点击home键|锁屏由Active - Inactive - Backgroud applicationWillResignActive applicationDidEnterBackground 3、重新进入前台Backgroud - Inactive - Active applicationWillEnterForeground applicationDidBecomeActive 4、在前台双击home键手动杀掉APPActive - Inactive - Backgroud - end applicationWillResignActive applicationDidEnterBackground applicationWillTerminate 当URL到达时如果你的应用没在正在运行则会被启动并且移到前台运行以打开URL application:didFinishLaunchingWithOptions: application:openURL:sourceApplication: applicationDidBecomeActive 当URL到达时如果你的应用正在background运行或被suspended它将会被移到前台以打开URL applicationWillEnterForeground application:openURL:sourceApplication: applicationDidBecomeActive
1.2.2全面的生命周期执行流程图 1.3 Main函数入口
基于C编写的app的入口都是main函数但iOS应用程序有点不同。不同就是你不需要为iOS应用程序而自己编写main函数当你使用Xcode创建工程的时候就已经提供了。除非一些特殊情况否则你不应该修改Xcode提供的main函数实现。示例代码如下
#import UIKit/UIKit.h
#import AppDelegate.hint main(int argc, char * argv[])
{autoreleasepool {return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));}
}上面实例代码中有一个很重要的函数UIApplicationMain它主要是创建app的几个核心对象来处理以下过程 从可用Storyboard文件加载用户界面调用AppDelegate自定义代码来做一些初始化设置将app放入Main Run Loop环境中来响应和处理与用户交互产生的事件 1.4 几个关键对象
UIApplication对象 用户与iOS设备交互时产生的事件(Multitouch EventsMotion EventRemote Control Event)交由UIApplication对象来分发给control objects(UIControl)对应的target objects来处理并且管理整个事件循环而一些关于app运行时重要事件委托给app delegate来处理。
App delegate对象 App delegate对象遵循UIApplicationDelegate协议响应app运行时重要事件(app启动、app内存不足、app终止、切换到另一个app、切回app)主要用于app在启动时初始化一些重要数据结构例如初始化UIWindow设置一些属性为window添加rootViewController。
View controller对象 View Controller有一个view属性是view层次结构中的根view你可以添加子view来构建复杂的viewcontroller有一些viewDidLoad、viewWillAppear等方法来管理view的生命周期由于它继承UIResponder所有还会响应和处理用户事件。
Documents和data model对象 data model对象主要用来存储数据。例如饿了么app在搜索切换地址后有历史记录搜索地址历史当app下次启动时读取和显示搜索地址历史。 document对象(继承UIDocument)用来管理一些或所有的data model对象。document对象并不是必须的但提供一种方便的方式来分组属于单个文件或多个文件的数据。
UIWindow对象 UIWindow对象位于view层次结构中的最顶层它充当一个基本容器而不显示内容如果想显示内容添加一个content view到window。 它也是继承UIResponder所以它也是会响应和处理用户事件。
View、control、layer对象 View对象可以通过addSubview和removeFromSuperview 等方法管理view的层次结构使用layoutIfNeeded和setNeedsLayout等方法布局view的层次结构当你发现系统提供view已经满足不了你想要的外观需求时可以重写drawRect方法或通过layer属性来构造复杂的图形外观和动画。还有一点UIView也是继承UIResponder所以也能够处理用户事件。 Control对象通常就是处理特定类型用户交互的View常用的有button、switch、text field等。 除了使用View和Control来构建view层次结构来影响app外观之外还可以使用Core Animation框架的Layer对象来渲染view外观和构建复杂的动画。
1.5 Main Run Loop
一个iOS应用程序的main run loop主要作用是处理所有与用户相关的事件。UIApplication对象在启动时就设置main run loop和使用它来处理事件和更新基于view的界面。正如它名字所示main run loop是运行在应用程序的主线程。这样就确保与接收到用户相关的事件被有序地处理。
下图显示main run loop的架构和用户事件最终是怎样被应用程序处理。当用户与设备交互时系统就会生成与交互关联的事件然后被应用程序的UIKit通过一个特殊的端口来分发。应用程序把事件放入队列然后逐个分发到main run loop来执行。UIApplication对象是第一个对象接收到事件然后决定怎样处理它。一个touch event通常都被分发到main window对象然后依次分发到发生触碰的view。其他event的接收事件对象路径可能有点不同。 大多数的事件通过使用main run loop来分发但有些不是。有些事件被发送到一个delegate对象或传递到你提供的block中。想了解更多如何处理大多数类型的事件其中包括touch、remote control、motion、accelerometer和gyroscopic等事件请查阅Event Handle Guide for iOS。
2. UI界面
ios中UI是按层来算的如下图新生成的界面都往上堆叠可以使用navigation controller来控制界面跳转而且都是带左上角返回图标的使用navigation controller之后这一系列页面都是可以使用其控制可以获取rootView。
2.1 UIWindow
有关UIWindow的介绍参考iOS开发UI篇–UIWindow简单介绍 UIWindow是一种特殊的UIView通常在一个app中只会有一个UIWindow iOS程序启动完毕后创建的第一个视图控件就是UIWindow接着创建控制器的view最后将控制器的view添加到UIWindow上于是控制器的view就显示在屏幕上了 一个iOS程序之所以能显示到屏幕上完全是因为它有UIWindow。也就说没有UIWindow就看不见任何UI界面 先创建UIwindow,再创建控制器创建控制器的view然后将控制器的view添加到UIWindow上。 2.2 UIViewController生命周期* ViewController是IOS开发中MVC模式中的CViewController是view的controllerViewController的职责主要包括管理内部各个view的加载显示和卸载同时负责与其他ViewController的通信和协调。在IOS中有两类ViewController 一类是显示内容的比如UIViewController、UITableViewController等同时还可以自定义继承自UIViewController的ViewController另一类是ViewController容器UINavigationViewController和UITabBarController等UINavigationController是以Stack的形式来存储和管理ViewControllerUITabBarController是以Array的形式来管理ViewController。 和Android中Activity一样IOS开发中ViewController也有自己的生命周期Lifecycle。 2.2.1 View的加载过程 从图中可以看到在view加载过程中首先会调用loadView方法在这个方法中主要完成一些关键view的初始化工作比如UINavigationViewController和UITabBarController等容器类的ViewController接下来就是加载view加载成功后会接着调用viewDidLoad方法这里要记住的一点是在loadView之前是没有view的也就是说在这之前view还没有被初始化。完成viewDidLoad方法后ViewController里面就成功的加载view了如上图右下角所示。
2.2.2 controller中创建view
在Controller中创建view有两种方式一种是通过代码创建、一种是通过xib的方式可视化创建后者可以比较直观的配置view的外观和属性Storyboard配合IOS6后推出的AutoLayout。通过xib或Storyboard创建view在Controller中创建view后会在Controller中对view进行一些操作会出现如下代码 xib方式官方推荐
通过storyboard拖拉的方式控件和事件通过拖拉对应然后通过xib加载
CCTableViewCell_nib *cell(CCTableViewCell_nib *)
[tableView dequeueReusableCellWithIdentifier:CellTableIdentifier
forIndexPath:indexPath];代码方式推荐 CCTableViewController *vc [[CCTableViewController alloc] init];[self.navigationController pushViewController:vc animated:YES];2.2.3 ViewController生命周期
当一个视图控制器被创建并在屏幕上显示的时候。 代码的执行顺序 1、 alloc 创建对象分配空间 2、init (initWithNibName|initWithCoder) 初始化对象初始化数据 3、awakeFromNib 所有视图的outlet和action已经连接但还没有被确定。 4、loadView 完成一些关键view的初始化工作加载view。 5、viewDidLoad 载入完成可以进行自定义数据以及动态创建其他控件 6、viewWillAppear 视图将出现在屏幕之前 7、viewWillLayoutSubviews 将要对子视图进行调整 8、viewDidLayoutSubviews 对子视图进行调整完毕 9、viewDidAppear 视图已在屏幕上渲染完成 10、viewWillDisappear 视图将被从屏幕上移除 11、viewDidDisappear 视图已经被从屏幕上移除 12、dealloc 视图被销毁此处需要对你在init和viewDidLoad中创建的对象进行释放 13、didReceiveMemoryWarning 内存警告
ViewController的生命周期中各方法执行流程如下 alloc - init - loadView - viewDidLoad - viewWillAppear - viewWillLayoutSubviews - viewDidLayoutSubviews - viewDidAppear - viewWillDisappear - viewDidDisappear - dealloc 2.3 navigation controller 在使用navigation controller时只需这样操作 在storyboard视图点击view页面在xcode导航栏选择Editor-Embed in-Navigation Controller即可使用self.navigationController控制页面跳转。 使用navigation controller控制页面代码类似这样 //点击按钮新建一个页面然后再写一个页面的controller代码里面控制下一个页面里的东西。
- (IBAction)buttonPressed:(UIButton *)sender {CCTableViewController *vc [[CCTableViewController alloc] init];[self.navigationController pushViewController:vc animated:YES];
}//点击tableview里面的cell然后实现页面跳转
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{//弹出当前界面返回上一层//[self.navigationController popViewControllerAnimated:YES];//返回到根页面//[self.navigationController popToRootViewControllerAnimated:YES];// 创建一个控制器将其页面设为绿色的空白页面UIViewController *vc [[UIViewController alloc] init];vc.view.backgroundColor [UIColor greenColor];[self.navigationController pushViewController:vc animated:YES];
}
2.4 WKWebView
WKWebView是iOS8推出的WKWebView有一个突出特点就是内存占用少。Webview的使用通常包含以下几个部分浏览器的基本设置浏览器的各种回调浏览器中js如何调用原生方法。 WKWebView基本使用 self.webview [[WKWebView alloc]init];[self.view addSubview:self.webview];[self.webview mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(self.view);make.right.equalTo(self.view);make.top.equalTo(self.view);make.bottom.equalTo(self.view);}];[_webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:http://www.baidu.com]]];WKWebView与其他WebView的基本使用没有太大区别将它当作一个普通的UIView进行布局然后调用loadRequest方法即可展示相应的网页。
WKWebView的设置 WKWebView的主要设置项都在configuration成员中比如是否允许浏览器手指缩放h5的浏览器能否自动播放等这些都属于浏览器本身的设置项。 在此列举几项及其作用由于类目繁多会有遗漏真正需要使用时可以在xcode的help中寻找查阅。 // 默认值为NO用户不可以放大或缩小页面如果设置为YES页面可以通过放大缩小去适应用户也可以通过手势来放大和缩小[self.webview.configuration ignoresViewportScaleLimits];//这个值决定了网页内容的渲染是否在把内容全部加载到内存中再去处理。如果设置为YES只有网页内容加载到内存里了才会去渲染[self.webview.configuration suppressesIncrementalRendering];// 默认使NO。这个值决定了用内嵌HTML5播放视频还是用本地的全屏控制。[self.webview.configuration allowsInlineMediaPlayback];// A Boolean value indicating whether AirPlay is allowed.[self.webview.configuration allowsAirPlayForMediaPlayback];// A Boolean value indicating whether HTML5 videos can play picture-in-picture.[self.webview.configuration allowsPictureInPictureMediaPlayback];// 网页中的多媒体是否需要手势才能开始播放iOS 10 可以设置仅音频需要、仅视频需要等四种状态self.webview.configuration.mediaTypesRequiringUserActionForPlayback WKAudiovisualMediaTypeNone;// 控制用户与webview进行选择交互时的粒度可以选择整个块儿或单个符号.self.webview.configuration.selectionGranularity WKSelectionGranularityDynamic;WKWebView的回调 WKWebView中包含了两个delegate。WKNavigationDelegate和WKUIDelegate。
WKNavigationDelegate 这个是WKWebView的导航的代理。它控制了WKWebView在加载一个页面流程中的各个关键时间节点的。相当于WKWebView加载的生命周期方法。
#pragma mark - WKNavigationDelegate
// 页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{NSLog(页面开始加载);
}
// 当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{NSLog(页面开始返回);
}
// 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{NSLog(页面完成加载);
}
// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{NSLog(页面加载失败);
}
// 接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{NSLog(页面重定向);
}
// 在收到响应后决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{NSLog(%,navigationResponse.response.URL.absoluteString);//允许跳转decisionHandler(WKNavigationResponsePolicyAllow);//不允许跳转//decisionHandler(WKNavigationResponsePolicyCancel);
}
// 在发送请求之前决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{NSLog(%,navigationAction.request.URL.absoluteString);//允许跳转decisionHandler(WKNavigationActionPolicyAllow);//不允许跳转//decisionHandler(WKNavigationActionPolicyCancel);
}WKUIDelegate WKUIDelegate控制了WKWebView的UI绘制。即我们可以掌管部分H5中的绘制行为。
#pragma mark - WKUIDelegate
// 创建一个新的WebView
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{return [[WKWebView alloc]init];
}
// 输入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{completionHandler(http);
}
// 确认框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{completionHandler(YES);
}
// 警告框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{NSLog(%,message);completionHandler();
}js调用原生方法 拦截url 此方法的本质是js会尝试加载某个URL客户端在加载前拦截这个URL通过解析这个URL识别它的内容调用相应的原生方法并阻上浏览器加载这个URL。 所以我们在decidePolicyForNavigationAction这个方法中进行拦截。
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{NSLog(%,navigationAction.request.URL.absoluteString);NSURL *url navigationAction.request.URL;NSString *urlStr url.absoluteString;if ([urlStr isEqualToString:xxx]) {// do something ;//不允许跳转decisionHandler(WKNavigationActionPolicyCancel);return;}//允许跳转decisionHandler(WKNavigationActionPolicyAllow);}contentController
A WKUserContentController object provides a way for JavaScript to post messages and inject user scripts to a web view.contentController苹果官方提供的js调用原生方法的类。它的使用方法是...self.contentController self.webview.configuration.userContentController;[_contentController addScriptMessageHandler:self name:closeWebView];...- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{if ([message.name isEqualToString:closeWebView]) {//做处理 do something//message.body 为此 ScriptMessage 传递的消息内容}
}js的调用方法
window.webkit.messageHandlers.事件名.postMessage(需要传递的数据)原生调用js方法
[self.webView evaluateJavaScript:function(action) completionHandler:nil];2.5 页面传值
大致有几种方式 参见页面传值的几种方式 由于iOS每一个大的页面都是由一个viewcontroller控制的其上的控件也由这个viewcontroller控制所以关键就是只要做好页面间的传值就好那么页面可以理解成一个类所以类之间的传值的方法也都是可以用的。
2.5.1 函数传值
对应与c中的方法由于下一个页面要在当前页面创建出来所以可以再下一个页面的controller中写一个方法在当前页面调用一下
//ViewControllerB.h
interface ViewControllerB : UIViewController
- (void)setValue(NSString *)value;
end//viewControllerA.h
interface ViewControllerA ()
property (nonatomic, copy) NSString *valueFromA;
- (void)btnClicked;
end
//ViewControllerA.m
- (void)btnClicked
{ViewControllerB *vcB [ViewControllerB new];[vcB setValue:valueFromA];[self.navigationController pushViewController:vcB animated:YES];
}
2.5.2 delegate传值
//ViewControllerB.h
//创建协议
protocol VcBDelegate NSObject
- (void)sendValue:(NSString *)value; //声明协议方法
end//ViewControllerB.h
interface ViewControllerB : UIViewController
property (nonatomic, weak)idVcBDelegate delegate; //声明协议变量
end//viewControllerA.m
interface ViewControllerA ()VcBDelegate//遵循协议
property (nonatomic, strong) UILabel *recievedLB;
end- (void)backActionClicked
{//当代理响应sendValue方法时把_tx.text中的值传到VCAif ([_delegate respondsToSelector:selector(sendValue:)]) {[_delegate sendValue:_tx.text];[self.navigationController popViewControllerAnimated:YES];}
}//ViewControllerA.m
- (void)btnClicked
{ViewControllerB *vcB [ViewControllerB new];vcB.delegate self;[self.navigationController pushViewController:vcB animated:YES];
}//ViewControllerA.m
//实现协议方法把接收到的值展示到Label中
- (void)sendValue:(NSString *)value
{_recievedLB.text value;
}
3. APP之间跳转方式
3.1 URL Scheme方式
调用正在运行的app 调用后台的APP
3.2 niversal Links方式
具体设置需要3步 1.App需要开启Associated Domains服务并设置Domains注意必须要applinks开头。 2.域名必须要支持HTTPS。 3.上传内容是Json格式的文件文件名为apple-app-site-association到自己域名的根目录下或者.well-known目录下。iOS自动会去读取这个文件。具体的文件内容请查看官方文档。
参考 iOS开发UI篇–UIWindow简单介绍 iOS应用程序的生命周期 iOS应用程序的生命周期_view WWDC 2018效率提升爆表的 Xcode 和 LLDB 调试技巧 iOS 组件化 —— 路由设计思路分析 iOS的WebView——WKWebView iOS APP生命周期 和 UIViewController的生命周期 iOS ViewController的生命周期 iOS 中delegate的理解与使用(传值)