iOS跑偏:零基础

内容源自视频内容摘取和总结:
https://www.bilibili.com/video/av49317023

1、OC语言的跑偏

1、如何掌握高级编程语言:

对于Oc来说,底层思维是基础,大型复杂项目需要用到面向对象思维。

底层思维 抽象思维
向下,如何把握机器底层从微观理解对象构造 向上,如何将我们的周围世界抽象为程序代码
语言构造
编译转换
内存模型
运行时机制
面向对象
组件封装
设计模型
构架模式

2、“时空人”三位一体分析法

  • 对时间分析——发生在什么时候?

    • compile-time VS run-time
  • 空间分析——变量放在那里?

    • stack VS heap
  • 人物分析——代码那里来的?

    • progranmmer VS compler/runtime/framework

    Hello World

//引入头文件,头文件.h,实现文件为.m
#import <Foundation/Faundation.h>
//函数入口点
int main(int argc, const char * argv[]){
	//为了支持ARC的pool
	@autoreleasepool{
		//@是Oc的字符串
		Nslog(@"Hello,World!")
	}
	return 0}

2、iOS的跑偏

2.1、App基本概念

2.1.1iOS App的代码结构
- main()
- UIapplicationMain():
	- main()函数中调用
	- 主要工作:①生成一个UIApplication对象;② 将UIApplicationDelegate返回给?
- UIApplication对象
- UIApplicationDelegate (我们的主要工作是管理这个)
  • iOS App的运行环境
    • Sandbox
    • 运行期目录结构
      • NSHomeDirectory()
2.1.2Bundle
  • IOS应用是一个Bundle
    • bundle:带有Info.plist的目录
    • NSBundle类
    • mainBundle
    • resource bundle 和 framework

2、基础理论支持

2.1.1界面和代码要分离
  • 可以只用代码来秒回界面及影响用户操作
  • 但是
    • 不直观
    • 调整麻烦
  • iOS的解决方案:
    • 用Interface Builder 画界面——保存到xib(xml版的nib文件)
      > nib:NEXTSTEP InterfaceBuilder

    • 用代码更新界面、影响用户的操作——保存到.m文件里

  • 两个小麻烦
  • 界面操作怎么制定相应代码
  • 代码怎么引用界面元素
实例化
开发时
代码:类
界面:模板xib
运行时
代码:类实例
界面:界面对象
  • Outlet
  • 为了让代码能引用nib中的对象
    • 需要代码里有一个变量来引用界面对象
    • 在界面对象创建后,给这个变量赋值
    • 这个过程最好能自动完成
  • Outlet
    • IBoutlet标记的变量
  • Connection
    在这里插入图片描述
    -Outlet Connection
<connection>
	//变量名:property="messageLabel"
	//引用的界面模板元素id:destination="Sik-hr-KEe"
	<outlet property="messageLabel" destination="Sik-hr-KEe" id="qCb-1M-csN" />
	<outlet property="nameField" destination="x9C-NC-3Hg" id="L1H-Uq-oGn" />
</ connections>
  • 存在xib里的是界面模板
  • 运行时,类实例的代码会出发界面实例化
    • 最终调用[UINib instantitateWithOwner:options];
    • 细节会在View Controler 部分讲解
  • 根据模板实例化其中的对象([UINib instantitateWithOwner:options])
  • [owner -setValue: uiObj forKey:outlet.property]—— 按照模板id??
  • Action Connection
-(IBAction)greeting:(id)sender{
//...
}

在这里插入图片描述

2.2 UIButton
Demo

输入名字点击按钮后出现打招呼信息
control+拖动控件到文件中实现了两个步骤:
1. 创建一个IBAction的方法
2. 方法和按钮的关联关系建立起来

-(IBAction)greeting:(id)sender{
    //get user name
    //compose message
    //show message
}

TextFaild声明:
- 1. 删除声明代码时,要把界面上的connection删除,不然会造成crash
- 2. 最好不要再头文件中书写,这样会暴露给外部(除非有暴露的需要)

@interface GameViewController ()
@property (weak, nonatomic) IBOutlet UITextField *nameField;
@end

代码充实:

-(IBAction)greeting:(id)sender{
    //get user name
    NSString * name = @"";
    name = self.nameField.text;
    //compose message
    NSString * message =@"";
    message = [NSString stringWithFormat: @"你好!%@!",name];
    //show message
    self.helloMessageShow.text = message;
}

作业遗留:

    1. 解决警告(如果没有输入值时怎么办)
    1. 尝试所有属性看看是做什么的
    1. 键盘会挡住界面,如何收起
UIbutton样式
  • 类型:Custom(可以自己定义图标样式)、System(系统)
  • 状态:Normal、Highlighted、Selected、Disabled
  • 文字与图片
  • 背景
  • 代码创建 UIButton
  • 创建
//buttonWithType可以保证不错漏一些信息
UIbutton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
  • 定制
[btn setBackgroundImage:[UIImage imageNamed:@"okBtn"]forState:UIControlStateNormal];
[btn setTitle:@"OK" forState: UIControlStateNormal];
[btn setTitleColor:[UIColor redColor forState:UIControlStateNormal]];
  • 添加响应
//action:@selector(greeting:) 一个方法的原型
//forControlEvents:UIControlEventTouchUpInside]  具体事件
[btn addTarget:self action:@selector(greeting:) forControlEvents:UIControlEventTouchUpInside];
2.3 Image
Domo
  • 在Xcode里管理Asset Catalog
    • 添加图片
    • 资源属性
    • 图片切片
  • UIImage View
    • 属性
      • View-Mode:缩放
      • state
      • 指定 Alpha:影响性能
    • 添加方式:
      • 在IB里选图片:直接拖动添加(指定名字加载)
      • 图片打包在mainBundle里
      • 系统自动缓存:会一直占用缓存无法清除
  • 在Assets.xcassets中设置图片
    • 图标设置
    • 图片设置(怎样适配不同设备)
    • 矢量图片(使用矢量图片,也要标记为矢量图片添加,并Universal)
    • slicing:指定位置不随放大缩小而变化
  • UIImage对象
  • 加载App bundle里的图片
image = [UIImage imageName:@"mypic"];//1
image = [UIImage imageName:@"mypic" inBundle:nil compatibleWithTraitCollection:nil];//2
NSURL * url = [[NSBundle mainBundle] URLForResource:@"mypic" withEntension:@"png"];
UIImage * image = [UIImage imageWithContentsOffile:url path];//3
  • 加载文件里的图片
UIIMage * image = [UIImage imageWithContentsOfFile:path];//2
UIImage * image = [UIImage imageWithData:date];//2
图片动画
  • 使用关键帧矢量图片
  • 建立outlet
- (voic)viewOldLoad{
	[super viewOldLoad];
	//Do any additional setup after loading the view, typically from a nib.
	UIImage * animatedImage = [UIImage @"dongtu" duration:1.0];//1秒
	self.animatedImageViewl.image = animatedImage;
}
矢量图片
- PDF格式的矢量图
	- llustrator或Inkscape导出PDF
	- 用Keynote也可以
- @1x 尺寸
- 在Assert Catalog里设置

2.2、第一个App

2.2.1 小游戏

需求:
1、显示图片
2、输入城市名字
3、猜对对得分,进入下一题
4、猜错不得分,进入下一题
在这里插入图片描述

2.2.1.1需求分析、设计

需求:
1、显示图片(展示图片的顺序没有说明,图片来源没说明)
2、输入城市名字(名字格式要求),
3、猜对对得分,进入下一题(多少分)
4、猜错不得分,进入下一题(猜错可以再尝试吗?)
5、一共几道题

设计需要划分几个大的模块

2.2.1.2 程序设计
Created with Raphaël 2.2.0 游戏开始画面 是否第一次开始 随机展示图片,等待作答 是否回答正确 加分 是否是最后一道题 展示开始页面+得分,游戏结束 是否重新开始 (是否已经有得分) yes no yes no yes no yes no
  • 静态结构+消息互动
  • 城市数据管理
    • 加载:
      • 城市硬编码成数组
      • 图片文件名:city+城市编号
      • 图片读取历程
    • 随机挑选:随机数生成
  • 游戏会话管理
    • 如何决定复杂度
2.2.1.3 示例代码的结构
城市图片
成绩
GameOver
猜名字
-init
--shufleCities
gessWithName:
--updageScore
--updageLevel
-- nextLevel
城市集
城市图片
jpg文件名匹配
最多三个
ViewController
UI
Game
CityDB
City
GameLevel
Guess
UIImage
  • 说明:
    1. 尽可能使用面向对象的思想,封装出最小的接口,隐藏最多的内部细节,同时操持良好的代码合作性的一套思路下
    1. UI是我们看得见的地方
    1. ViewController是termlit??生成给你的,它负责承上启下,把内部的状态展示在界面上,把界面上的动作清理成一条消息发给我们的程序主体部分(Game对象)
    1. ViewController与Game的消息来往
    • 4.1. ViewController找Game要城市的图片,要当前的进展,游戏有没有结束,把用户提供的名字发给游戏猜的方法
    • 4.2 所有的核心逻辑都在Game这个类里面
    1. Game
    • 5.1 CityDB:
      • GameLevel 游戏关卡,每个城市封装成一个关卡,对应城市对象
      • 每个城市ID封装成CityDB这个对象,使用时在内存中加载
      • CityDB对象实际上只保留了一组City对象的引用,实际上是没有图片的,只有City的ID和名字
      • 图片文件放在UIImage里面,每个文件以“city{id}.jpg”的方式命名
      • CityDBload的时候,给了Game一个City的数组
      • 当Game找CityDB要图片时,它把id拿出来拼成cityid.jpg,然后用UIImage从文件里把它load出来的
    • 5.2 游戏本身的主体逻辑是什么?(初始化和准备工作)
      • 初始化最关键的部分是ShuffleCities,CityDB提供的数组每次都是一样的,Game里面在初始化的时候需要“洗牌”,每个城市创建出一个GameLevel出来,不再是City加载出来的顺序了。
      • 当用户的动作通过ViewController以一个猜+名字的参数消息发给Game的时候,Game的GameWithName方法就开始做工作了:
        • 首先去比较一下猜对了没有,根据结果调用updateScore方法,去更新他的成绩。这样成绩计算是个独立的函数,将来可以很方便的去调整
        • updateLevel:
          • 把用户的一次猜测,封装成一个对象注册到GameLevel中判断一下,现在这个GameLevel里面的Guess次数是不是够多,够多的话就失败进入下一关;已经猜对了直接进入下一关
          • nextLevel:在Game关卡切换里面还包含了游戏有没有玩到最后一关的判断逻辑
2.2.1.4 Domo
  • 在Xocde里写出来
    • 画界面
    • 编写基础类
    • 编写主程序
2.2.2 扫雷简单版(课外自己练习)
需求

游戏区包括雷区、地雷计数器(位于左上角,记录剩余地雷数)和计时器(位于右上角,记录游戏时间),确定大小的矩形雷区中随机布置一定数量的地雷(初级为99个方块10个雷,中级为1616个方块40个雷,高级为1630个方块99个雷,自定义级别可以自己设定雷区大小和雷数,但是雷区大小不能超过2430),玩家需要尽快找出雷区中的所有不是地雷的方块,而不许踩到地雷。

需求分析与整理

1、雷区
大小:16*16的方块
方格状态:初始、打开(1-8、空)、引爆、胜利
雷区状态:剩余未打开数量为40时,胜利
2、计时器

程序设计
Created with Raphaël 2.2.0 游戏开始画面,展示开始按钮 初始化16*16的按钮, 其中40个是雷,其他216为数字、空白, 所有按钮未打开状态,计时器为0 用户点击按钮 开始计时 是不是雷 提示失败 停止计时 是否不再玩了 展示开始按钮, 保持现状 剩40个未开? 提示胜利 yes no yes no yes no
  • 雷区数据处理
    • 加载:
      • 雷区按钮数组
      • 雷、数字、空白的逻辑关系
      • 按钮展开与未展开状态
    • 随机生成类
  • 界面交互处理

成绩
时间
GameOver
PushBox
-init
--shuffleLeiArry
-pushBox
--updateScore
updateGameLevel
--updageTime
ViewController
UI
Game
LeiArray
GameLevel
UIButton
PushBox
InnerValue

LeiArray–>LeiButton
GameLevel–>|列表大小|LeiArray
LeiButton–>UIButton
PushBox–>|改变状态|UIButton
InnerValue–>1-8/0/9

  • 说明:
    1. ViewController与Game的消息来往
    • . ViewController找Game雷区按钮(状态与数字),要当前的进展,要当前时间,游戏有没有结束,把用户提供重新开始、推格子信息发给Game
    • 所有的核心逻辑都在Game这个类里面
    1. Game
    • 5.1 LeiArray:
      • GameLevel 游戏级别,分为初级、中级、高级、自选,将级别信息提供给LeiArray,决定列表大小、雷的数量
      • 每个UIBotton的展示数字、状态,封装到LeiButton中
      • CityDB对象实际上只保留了一组UIButton对象的样式状态,
      • 按钮存放UIButton里面,每个button有0-9,open/close来两个维度
      • LeiArray load的时候,给了Game一个LeiButton数组
      • 当Game找LeiButton要按钮展示时,它把每个按钮状态拿出来,拼成二位UIButton数组,然后UIButton根据状态和数字,展示对应的按钮
    • 5.2 游戏本身的主体逻辑是什么?(初始化和准备工作)
      • 初始化最关键的部分是ShuffleLei,LeiArray提供的数组每次都是一样的,Game里面在初始化的时候需要“洗牌”,每个UIButton创建出一个数字出来,不再是City加载出来的顺序了。
      • 当用户的动作通过ViewController以一个猜+名字的参数消息发给Game的时候,Game的GameWithName方法就开始做工作了:
        • 首先去比较一下猜对了没有,根据结果调用updateScore方法,去更新他的成绩。这样成绩计算是个独立的函数,将来可以很方便的去调整
        • updateLevel:
          • 把用户的一次猜测,封装成一个对象注册到GameLevel中判断一下,现在这个GameLevel里面的Guess次数是不是够多,够多的话就失败进入下一关;已经猜对了直接进入下一关
          • nextLevel:在Game关卡切换里面还包含了游戏有没有玩到最后一关的判断逻辑
            (未完成)

3、storyBoard的跑偏

  1. 自动创建的SingleViewApp,就已经将Main.storyboard和ViewController

    1. ViewController就相当于C语言中的main函数:应用程序的主入口。但是这个入口可以改
    2. storyboard从字面意思上理解就是故事板
    3. 与storyboard功能类似的还有Xib
  2. storyboard

    1. 可以直接将控件拖入(画一些情节),转化到应用程序上就是一个个的控件
    2. 比较适合偏重于快速搭建复杂的静态页面 ,xib较为轻量级
  3. 将两个页面链接起来

    1. 新建A页面,在页面添加按钮,添加事件:
    //我这里给按钮添加outlet的时候,事件是空心的??而且因为命名原因?已经关联到storyboard中的exit,无法使用这个方法,先忽略
    - [IBAction]closeButton:(id)sender{
    	    [self dismissViewControllerAnimated:YES completion:^()];
     }
    
    1. 在mainViewController中添加进入A页面的按钮
    //在ViewController.m文件中添加
    #import "StartViewController.h"
    - (IBAction)enterBtn:(id)sender{
    	//如果还是以对象的创建方式new一个或alot一个init的话,拿不到testStoryboard下面的东西
    	//拿到刚才创建的testStoryboard
    	UIStoryboard * newS = [UIStoryboard storyboardWithName:@"StartStoryboard" bundle:nil];
    	//通过storyboard创建出与他关联的那个viewController
    	StartViewController *vc = [newS instantiateViewControllerWithIdentifier:@"StartViewController"];
    	//以模态视图的方式创建出来
    	[self presentViewController:vc animated:YES completion:^{}];
      }
    
    1. debug发生崩溃,找到有用信息,确认是名字写错了= =

      ‘NSInvalidArgumentException’, reason: 'Could not find a storyboard named ‘StartStoryboard’ in bundle NSBundle

    2. 有发生崩溃:New File的时候没有选UIController的原因,所以.m文件没有按照UIViewController模式创建

    ‘NSInvalidArgumentException’, reason: ‘Storyboard (<UIStoryboard: 0x28035b1c0>) doesn’t contain a view controller with identifier ‘StartStoryboard’’

    1. 有发生崩溃,StartStoryboard添加identity-StoryboardID也不行,可能是版本问题,勾选UseStorybored ID后,终于解决了

    ‘NSInvalidArgumentException’, reason: ‘Storyboard (<UIStoryboard: 0x28035b1c0>) doesn’t contain a view controller with identifier ‘TestViewController’’

  4. 在一个Storyboard中放更多的ViewController:

    1. 与上面一样,新创建的ViewController就需要新建一个.m&.h文件与他关联
    2. 在同一个Storyvoard中,按住Control可以将A视图拖动到B视图,(因为没有加导航控制器)只能以模态的方式去把从A视图把B视图中展示出来
  5. 延伸:页面dissmiss

  6. 本段Stroyboar摘抄来源

3、计时器的跑偏

本段引用来源
本段引用

1. 获取当前时间

+(NSString*)getCurrentTimes{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    // ----------设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制
    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
    //现在时间,你可以输出来看下是什么格式
    NSDate *datenow = [NSDate date];
    //----------将nsdate按formatter格式转成nsstring
    NSString *currentTimeString = [formatter stringFromDate:datenow];
    NSLog(@"currentTimeString =  %@",currentTimeString);
    return currentTimeString;
}
  • (因为不懂代码所以还没验证,只是按时间总结):
    • 封装的内部类写在@implementation之中,同时将名字添加到@interface中声明

本节跑偏总结/复习思路:

1.创建工程:一般工程都用SingleView Application,其他类型都是自带模板的
2. 页面上的UI控件,需要outlet创建变量并建立关联后使用
3. UIButton、TextFail、UIImage控件的入门使用
4.写一个APP(一个功能)的开发流程
4. storyBoard和ViewController之间的关系,简单应用

还没整理的链接记录:
自动化框架总结
2020年Top API测试工具
阿里-性能测试技术指南
阿里-Python脚本测试
基于 Jenkins 的 CI/CD(二)
Xcode快捷键
Xcode自带iOS测试方法
xcode构建webdriverAgent时报错Messaging unqualified id的解决办法
Xcode创建终端命令
iOS------获取当前时间和当前时间戳
iOS 中的几种常用定时器
经典的测试开发面试题
SwiftUI构建完整应用
入门
三种收起键盘的方法
收起键盘2

发布了4 篇原创文章 · 获赞 0 · 访问量 47

猜你喜欢

转载自blog.csdn.net/tongqingshuo/article/details/104264086