[iOS基础控件 - 6.11.3] 私人通讯录Demo 控制器的数据传递、存储
- 账号
- 密码
- 记住密码开关
- 自动登陆开关
- 登陆按钮

- 输入账号密码
- 记住密码、自动登录开关
- 登陆跳转按钮
- 注销功能
- 添加联系人跳转按钮


1 /* 登陆按钮监听账号、密码输入框的通知
2 * 只有当两者都有内容的时候才能激活登陆按钮
3 */
4 - (void) loginButtonListening{
5 // 监听账号输入
6 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:self.accountText];
7
8 // 监听密码输入
9 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:self.pwdText];
10 }
11
12 // 记得要在自身被销毁的时候取消消息订阅
13 - (void)dealloc {
14 [[NSNotificationCenter defaultCenter] removeObserver:self];
15 }
16
17 // 登陆按钮监听的触发事件
18 - (void) textChange {
19 // 只有当账号、密码不为空的时候,才能使用登陆按钮
20 self.loginButton.enabled = self.accountText.text.length && self.pwdText.text.length;
21 }
/** 点击登陆 */
- (IBAction)login {
// 检测账号
if (![self.accountText.text isEqualToString:@"hw"]) {
NSLog(@"账号不存在");
return;
} // 检测密码
if (![self.pwdText.text isEqualToString:@"123"]) {
NSLog(@"密码不正确");
return;
} // 根据Segue ID 执行跳转
[self performSegueWithIdentifier:@"contactList" sender:nil];
}


1 /** 点击登陆 */
2 - (IBAction)login {
3 // 检测账号
4 if (![self.accountText.text isEqualToString:@"hw"]) {
5 [MBProgressHUD showError:@"账号不存在"];
6 return;
7 }
8
9 // 检测密码
10 if (![self.pwdText.text isEqualToString:@"123"]) {
11 [MBProgressHUD showError:@"密码错误"];
12 return;
13 }
14
15 // 登陆中,遮盖屏幕,禁止用户进行其他操作
16 [MBProgressHUD showMessage:@"正在使劲登录中..."];
17
18 // 模拟登陆过程,延迟跳转
19 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
20 // 移除遮盖
21 [MBProgressHUD hideHUD];
22
23 // 根据Segue ID 执行跳转
24 [self performSegueWithIdentifier:@"contactList" sender:nil];
25 });
26 }

1 // 根据Segue ID 执行跳转
2 [self performSegueWithIdentifier:@"contactList" sender:nil];
1 /** 点击记住密码 */
2 - (IBAction)keepPwdSwitch {
3 if (!self.keepPwd.isOn) {
4 [self.autoLogin setOn:NO];
5 }
6 }
7
8 /** 点击自动登陆 */
9 - (IBAction)autoLoginSwitch {
10 if (self.autoLogin.isOn) {
11 [self.keepPwd setOn:YES];
12 }
13 }

1 /** 点击注销 */
2 - (IBAction)logout:(UIBarButtonItem *)sender {
3 UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"确定要注销?" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"确定" otherButtonTitles:nil, nil];
4
5 [sheet showInView:self.view];
6 }
7
8 #pragma mark - ActionSheet delegate function
9 - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
10 if (buttonIndex != 0) return;
11
12 // 弹出一个栈顶控制器,即本控制器,回到上一页
13 [self.navigationController popViewControllerAnimated:YES];
14 }



1 - (void)viewDidLoad {
2 [super viewDidLoad];
3 // Do any additional setup after loading the view.
4
5 // 设置“添加”按钮的激活状态
6 self.addButton.enabled = NO;
7 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:self.nameText];
8 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:self.phoneText];
9 }
10
11 - (void)dealloc {
12 // 取消订阅消息监听
13 [[NSNotificationCenter defaultCenter] removeObserver:self];
14 }
15
16 /** 姓名、电话文本编辑消息处理
17 * 只有当姓名、电话不为空的时候才能使用“添加”按钮
18 */
19 - (void) textChange {
20 self.addButton.enabled = self.nameText.text.length && self.phoneText.text.length;
21 }
1 // 等界面完全显示完毕,再弹出键盘
2 - (void)viewDidAppear:(BOOL)animated {
3 [super viewDidAppear:animated];
4
5 // 将焦点放在“姓名”输入框
6 [self.nameText becomeFirstResponder];
7 }
1 /** 点击添加按钮 */
2 - (IBAction)add {
3 // 1.关闭当前控制器
4 [self.navigationController popViewControllerAnimated:YES];
5
6 // 2.使用模型传递数据给上一个控制器(ContactListViewController),使用代理通知数据更新
7 Contact *contact = [[Contact alloc] init];
8 contact.name = self.nameText.text;
9 contact.phone = self.phoneText.text;
10 [self.delegate addViewController:self didAddedContact:contact];
11 }
1 #pragma mark - AddViewController delegate function
2 /** 添加联系人后,更新联系人列表数据 */
3 - (void)addViewController:(AddViewController *)addViewController didAddedContact:(Contact *)contact {
4 NSMutableArray *mcontacts = [NSMutableArray arrayWithArray:self.contacts];
5 [mcontacts addObject:contact];
6 self.contacts = mcontacts;
7 [self.tableView reloadData];
8 }



1 + (instancetype) cellWithTableView:(UITableView *) tableView {
2 // cell ID 要在storyboard中设置好
3 static NSString *ID = @"contactCell";
4 // 先从缓存池寻找,如果找不到就从storyboard中创建一个
5 return [tableView dequeueReusableCellWithIdentifier:ID];
6 }
1 #pragma mark - Segue相关
2 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
3 // 取得目标控制器
4 id controller = segue.destinationViewController;
5
6 // 判断跳转目标
7 if ([controller isKindOfClass:[AddViewController class]]) {
8 // 如果是“添加联系人”
9 AddViewController *addViewController = controller;
10 addViewController.delegate = self;
11 }
12
13 if ([controller isKindOfClass:[EditViewController class]]) {
14 // 如果是“查看/编辑联系人”
15 EditViewController *editViewController = controller;
16
17 // 取出数据
18 NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
19 editViewController.contact = self.contacts[indexPath.row];
20
21 // 设置代理
22 editViewController.delegate = self;
23 }
24
25 }
1 - (void)viewDidLoad {
2 [super viewDidLoad];
3 // Do any additional setup after loading the view.
4
5 // 加载数据
6 self.nameText.text = self.contact.name;
7 self.phoneText.text = self.contact.phone;
8
9 // 设置输入监听
10 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:self.nameText];
11 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:self.phoneText];
12 }


1 /** 点击“编辑”或"取消” */
2 - (IBAction)editOrCancel:(UIBarButtonItem *)sender {
3 // 转变后的状态
4 BOOL isChangedToEditMode = [sender.title isEqualToString:@"编辑"]? YES:NO;
5
6 if (isChangedToEditMode) {
7 // 点击"编辑"
8 // 1.转变title
9 sender.title = @"取消";
10
11 // 2.转变编辑状态
12 self.nameText.enabled = YES;
13 self.phoneText.enabled = YES;
14 self.saveButton.hidden = NO;
15
16 // 获得输入焦点
17 [self.nameText becomeFirstResponder];
18 } else {
19 // 点击“取消”
20 // 1.转变title
21 sender.title = @"编辑";
22
23 // 2.转变编辑状态
24 self.nameText.enabled = NO;
25 self.phoneText.enabled = NO;
26 self.saveButton.hidden = YES;
27
28 // 3.还原数据
29 self.nameText.text = self.contact.name;
30 self.phoneText.text = self.contact.phone;
31
32 // 4.退出键盘
33 [self.view endEditing:YES];
34 }
35
36 }
37
38 /** 消息监听事件 */
39 - (void) textChange {
40 self.saveButton.enabled = self.nameText.text.length && self.phoneText.text.length;
41 }
1 #pragma mark - EditViewController delegate function
2 /** “编辑联系人”的“保存”代理方法, 刷新数据 */
3 - (void)editViewController:(EditViewController *)editViewController didSavedContact:(Contact *)contact {
4 [self.tableView reloadData];
5 }


1 /**
2 * 如果cell是通过storyboard或者xib创建,不会调用此方法
3 * 如果使用代码创建cell,才会调用这个方法来初始化cell
4 */
5 - (instancetype) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
6 NSLog(@"initWithStyle");
7 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
8 return self;
9 }
1 /**
2 * 如果cell是通过storyboard或者xib创建,创建完毕会调用这个方法
3 * 可以在这里初始化cell
4 */
5 - (void) awakeFromNib {
6 // 自定义一个分割线
7 UIView *divideLine = [[UIView alloc] init];
8 [divideLine setBackgroundColor:[UIColor blackColor]];
9 [divideLine setAlpha:0.2];
10 [self.contentView addSubview:divideLine];
11 self.divideLine = divideLine;
12 }
13
14 /**
15 * 在此方法中,cell的frame确定被初始化完成,可以再这里初始化其子控件的frame
16 */
17 - (void)layoutSubviews {
18 // 切记调用父类方法!
19 [super layoutSubviews];
20
21 CGFloat lineHeight = 1;
22 CGFloat lineWidth = self.frame.size.width;
23 CGFloat lineX = 0;
24 CGFloat lineY = self.frame.size.height - 1;
25
26 self.divideLine.frame = CGRectMake(lineX, lineY, lineWidth, lineHeight);
27 }
- xml属性列表(plist)归档
- Preference(偏好设置)
- NSKeyedArchiver归档
- SQLite3数据库(关系型数据库)
- Core Data
1 #pragma mark - AddViewController delegate function
2 /** 添加联系人后,更新联系人列表数据 */
3 - (void)addViewController:(AddViewController *)addViewController didAddedContact:(Contact *)contact {
4 NSMutableArray *mcontacts = [NSMutableArray arrayWithArray:self.contacts];
5 [mcontacts addObject:contact];
6 self.contacts = mcontacts;
7
8 // 保存数据到plist文件
9 [self saveContactsDataToFile];
10
11 // 刷新界面数据
12 [self.tableView reloadData];
13 }
14
15 #pragma mark - EditViewController delegate function
16 /** “编辑联系人”的“保存”代理方法, 刷新数据 */
17 - (void)editViewController:(EditViewController *)editViewController didSavedContact:(Contact *)contact {
18 // 保存数据
19 [self saveContactsDataToFile];
20 // 刷新数据
21 [self.tableView reloadData];
22 }
23
24 #pragma mark - 加载、保存、读取数据
25 /** 保存联系人数据到plist */
26 - (void) saveContactsDataToFile {
27 // 沙盒路径
28 NSString *path = NSHomeDirectory();
29 // Documents路径
30 NSString *docPath = [path stringByAppendingPathComponent:@"Documents"];
31 // plist文件路径
32 NSString *filePath = [docPath stringByAppendingPathComponent:@"contacts.plist"];
33
34 NSMutableArray *dictArray = [NSMutableArray array];
35 for (Contact *contact in self.contacts) {
36 // 将模型转换成字典进行存储
37 NSDictionary *dict = [Contact dictionaryWithContact:contact];
38 [dictArray addObject:dict];
39 }
40 [dictArray writeToFile:filePath atomically:YES];
41 NSLog(@"save to : %@", filePath);
42 }
1 /** 加载数据 */
2 - (NSArray *) contacts {
3 if (nil == _contacts) {
4 // 沙盒路径
5 NSString *path = NSHomeDirectory();
6 // Documents路径
7 NSString *docPath = [path stringByAppendingPathComponent:@"Documents"];
8 // plist文件路径
9 NSString *filePath = [docPath stringByAppendingPathComponent:@"contacts.plist"];
10
11 // 如果plist文件不存在
12 NSFileManager *fileManager = [NSFileManager defaultManager];
13 if (![fileManager fileExistsAtPath:filePath]) {
14 _contacts = [NSArray array];
15 return _contacts;
16 }
17
18 // 如果plist文件存在,开始读取
19 NSArray *contacts = [NSArray arrayWithContentsOfFile:filePath];
20 NSMutableArray *mcontacts = [NSMutableArray array];
21 for (NSDictionary *dict in contacts) {
22 Contact *contact = [Contact contactWithDictionary:dict];
23 [mcontacts addObject:contact];
24 }
25
26 _contacts = mcontacts;
27 }
28
29 return _contacts;
30 }
1 /**
2 * 把初始化代码放在viewDidAppear
3 * 让view完全呈现之后才进行自动登陆,否则拿不到view,hideHUD的时候会失效
4 */
5 - (void)viewDidAppear:(BOOL)animated {
6 // 设置登陆状态
7 [self readLoginStatus];
8
9 // 初始化登陆按钮状态
10 if (!self.accountText.text.length || !self.pwdText.text.length) {
11 self.loginButton.enabled = NO;
12 }
13
14 // 登陆按钮开始监听账号、密码输入框
15 [self loginButtonListening];
16 }
17
18 /** 读取登陆状态 */
19 - (void) readLoginStatus {
20 // 记住密码、自动登录开关状态
21 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
22 self.keepPwd.on = [defaults boolForKey:@"keepPwd"]? YES:NO; // 防止键值对为nil
23 self.autoLogin.on = [defaults boolForKey:@"autoLogin"]? YES:NO;
24
25 // 账号、密码
26 if (self.keepPwd.isOn) {
27 self.accountText.text = [defaults objectForKey:@"account"];
28 self.pwdText.text = [defaults objectForKey:@"pwd"];
29 }
30
31 // 自动登陆
32 if (self.autoLogin.isOn) {
33 [self login];
34 }
35 }
1 /** 点击登陆 */
2 - (IBAction)login {
3 // 检测账号
4 if (![self.accountText.text isEqualToString:@"hw"]) {
5 [MBProgressHUD showError:@"账号不存在"];
6 return;
7 }
8
9 // 检测密码
10 if (![self.pwdText.text isEqualToString:@"123"]) {
11 [MBProgressHUD showError:@"密码错误"];
12 return;
13 }
14
15 // 登陆中,遮盖屏幕,禁止用户进行其他操作
16 [MBProgressHUD showMessage:@"正在使劲登录中..."];
17
18 // 模拟登陆过程,延迟跳转
19 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
20 // 移除遮盖
21 [MBProgressHUD hideHUD];
22
23 // 根据Segue ID 执行跳转
24 [self performSegueWithIdentifier:@"contactList" sender:nil];
25 });
26
27 // 保存登陆状态
28 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
29 [defaults setBool:self.keepPwd.isOn forKey:@"keepPwd"];
30 [defaults setBool:self.autoLogin.isOn forKey:@"autoLogin"];
31
32 // 保存账号、密码信息
33 if (self.keepPwd.isOn) {
34 [defaults setObject:self.accountText.text forKey:@"account"];
35 [defaults setObject:self.pwdText.text forKey:@"pwd"];
36 }
37 }

1 /** 自动登陆标识 */
2 @property(nonatomic, assign) BOOL stopAutoLogin;
3
4 - (void)viewDidDisappear:(BOOL)animated {
5 // 当不是初次出现在屏幕上,禁止自动登陆
6 self.stopAutoLogin = YES;
7 }
8
9 /** 读取登陆状态 */
10 - (void) readLoginStatus {
11 // 记住密码、自动登录开关状态
12 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
13 self.keepPwd.on = [defaults boolForKey:@"keepPwd"]? YES:NO; // 防止键值对为nil
14 self.autoLogin.on = [defaults boolForKey:@"autoLogin"]? YES:NO;
15
16 // 账号、密码
17 if (self.keepPwd.isOn) {
18 self.accountText.text = [defaults objectForKey:@"account"];
19 self.pwdText.text = [defaults objectForKey:@"pwd"];
20 }
21
22 // 自动登陆
23 if (!self.stopAutoLogin && self.autoLogin.isOn) {
24 [self login];
25 }
26 }
1 /**
2 * 如果实现了这个方法,就自动实现了滑动删除功能
3 * 点击了“删除”按钮就会调用
4 * 实质是提交了一个编辑操作导致调用(删除/添加/编辑)
5 * @param editingStyle 编辑行为
6 * @param indexPath 操作行号
7 */
8 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
9 // 如果是删除操作
10 if (editingStyle == UITableViewCellEditingStyleDelete) {
11 // 1.删除数据
12 NSMutableArray *marray = [NSMutableArray arrayWithArray:self.contacts];
13 [marray removeObjectAtIndex:indexPath.row];
14 self.contacts = marray;
15
16 // 2.刷新界面
17 // [self.tableView reloadData];
18 // 只删掉需要删除的一行,不必刷新所有数据
19 // 使用这个方法,必须删除对应的模型数据,数量要对应
20 [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
21
22 // 3.更改plist数据
23 [self saveContactsDataToFile];
24 }
25 }


1 - (void)viewDidLoad {
2 [super viewDidLoad];
3
4 // 设置无系统自带分割线
5 [self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
6
7 // 取出原来在storyboard中创建的“+”按钮
8 UIBarButtonItem *addItem = self.navigationItem.rightBarButtonItem;
9
10 // 创建一个“垃圾桶”按钮
11 UIBarButtonItem *deleteItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(deleteCheck)];
12
13 // 都放入到右边的状态栏
14 self.navigationItem.rightBarButtonItems = @[deleteItem, addItem];
15 }
1 // 点击状态栏按钮“垃圾桶”,使所有cell进入编辑状态或者退出编辑状态
2 - (void) deleteCheck {
3 // self.tableView.editing = !self.tableView.editing;
4 [self.tableView setEditing:!self.tableView.editing animated:YES];
5 }
1 // 改变编辑状态下的编辑按钮
2 - (UITableViewCellEditingStyle) tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
3 if (indexPath.row == 0) {
4 // 这里改为“添加”符号,需要自定义事件
5 return UITableViewCellEditingStyleInsert;
6 } else if (indexPath.row == 1) {
7 // none就是什么都没有,没有作用
8 return UITableViewCellEditingStyleNone;
9 } else {
10 // 默认就是“删除”
11 return UITableViewCellEditingStyleDelete;
12 }
13 }

[iOS基础控件 - 6.11.3] 私人通讯录Demo 控制器的数据传递、存储的更多相关文章
- [iOS基础控件 - 6.11.4] storyboard 的 Segue
A.概念 storyboard中的跳转事件连线,都是一个UIStoryboardSegue对象(Segue) 来源控制器 触发控制器 目标控制器 跳转到的控制器 Seg ...
- [iOS基础控件 - 6.9.1] 聊天界面Demo 代码
框架: 所有代码文件: Model: // // Message.h // QQChatDemo // // Created by hellovoidworld on 14/12/8. // ...
- [iOS基础控件 - 6.11.5] 沙盒 & 数据存储
A.沙盒 每个APP都有一个沙盒,是独立存在的 1.Xcode5和Xcode6的模拟器文件目录 a.模拟器路径改版 (1)Xcode5中模拟器路径为:/Users/用户名/Library/Appl ...
- [iOS基础控件 - 6.11.2] - UINavigationController 多控制器 简单使用
A.概念 1.通常一个app有多个控制器 2.需要对这些控制器进行管理 3.有多个view的时候,用一个父view去管理多个子view 4.控制器管理也是如此,使用给一个父控制器,去控制子控制器 ...
- [iOS基础控件 - 6.11.1] - 控制器 & 控制器view
A.控制器的创建 控制器常见的创建方式有以下几种通过storyboard创建 直接创建 ViewController *vc = [[ViewController alloc] init]; ...
- [iOS基础控件 - 5.5] 代理设计模式 (基于”APP列表"练习)
A.概述 在"[iOS基础控件 - 4.4] APP列表 进一步封装,初见MVC模式”上进一步改进,给“下载”按钮加上效果.功能 1.按钮点击后,显示为“已下载”,并且不 ...
- [iOS基础控件 - 6.12.3] @property属性 strong weak copy
A.概念 @property 的修饰词 strong: 强指针/强引用(iOS6及之前是retain) weak: 弱智真/弱引用(iOS6及之前是assign) 默认情况所有指针都是强指针 ...
- iOS 基础控件(下)
上篇介绍了UIButton.UILabel.UIImageView和UITextField,这篇就简短一点介绍UIScrollView和UIAlertView. UIScrollView 顾名思义也知 ...
- [iOS基础控件 - 7.0] UIWebView
A.基本使用 1.概念 iOS内置的浏览器控件 Safari浏览器就是通过UIWebView实现的 2.用途:制作简易浏览器 (1)基本请求 创建请求 加载请求 (2)代理监听webView加载, ...
随机推荐
- [HDOJ4612]Warm up(双连通分量,缩点,树直径)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 所有图论题都要往树上考虑 题意:给一张图,仅允许添加一条边,问能干掉的最多条桥有多少. 必须解决 ...
- 自己动手实现STL 02:构造析构的基本工具construct()和destroy()(stl_construct.h)
一.前言 上一篇,我先完成了对内存配置器的实现.然而后面在内存上的算法还依赖于两个全局函数,construct()和destroy(),前者负责在指定的内存上调用对象的构造函数,在内存上构造出对象.后 ...
- poj 1151 Atlantis (离散化 + 扫描线 + 线段树 矩形面积并)
题目链接题意:给定n个矩形,求面积并,分别给矩形左上角的坐标和右上角的坐标. 分析: 映射到y轴,并且记录下每个的y坐标,并对y坐标进行离散. 然后按照x从左向右扫描. #include <io ...
- bzoj2432
被虐的体无完肤, 直接给题解地址吧:http://vfleaking.blog.163.com/blog/static/174807634201341721051604/ ; ..,..] of in ...
- ADO和DAO的区别
ADO(ACTIVEX DATA OBJECTS)应用层的数据访问接口ODBC 数据库驱动接口OLE DB 系统级数据访问接口DAO (DATA ACCESS OBJECTS) 对象的数据访问接口AD ...
- codeforces 334A - Candy Bags
忘了是偶数了,在纸上画奇数画了半天... #include<cstdio> #include<cstring> #include<cstdlib> #include ...
- LeetCode Maximum Product Subarray 最大子序列积
题意:给一个size大于0的序列,求最大的连续子序列之积.(有正数,负数,0) 思路:正确分析这三种数.0把不同的可能为答案的子序列给隔开了,所以其实可以以0为分隔线将他们拆成多个序列来进行求积,这样 ...
- HDU 1269 迷宫城堡 (强连通分量,常规)
题意: 判断所给的有向图是否是一个强连通图. 思路: 如果连通分量大于1则必定No,如果强连通分量大于1也是No.tarjan算法求强连通分量. #include <cstdio> #in ...
- Nginx & AWStats 安装、配置、使用
—— 参考IBM文章:THIS , 不一样的指导顺序 —— 1. awstats分析nginx - access.log,网上资料大部分都是下载,然后配置.官网下载地址: http://awstats ...
- 专题:Windows编译x264、SDL、faac、ffmpeg过程
Windows上编译ffmpeg完整过程,包括编译x264.SDL.faac.在Windows上编译ffmpeg需要用MinGW+msys,本专题用于记录编译过程中遇到的各种问题及解决方法,转载请注明 ...