iOS技术知识盘点一(全面覆盖技术知识点)


1> 主界面上下水波动态显示

2> 导入音乐铃声
  • 根据MJAutoTool 实现

3> 语言本地化通过2个string文件实现
  • (在plist文件中完成NSLocation加载语言本地化)
  • NSLocalizedString(@"本地化",nil)

4> 铃声的处理用 [ NSUserDefaults standardUserDefaults ]单例实现

5> 归档和本地化存储操作来了解控制器的生命周期和如何设计代码

6> 研究自定义 UIAlertView但是iOS9.0之后建议使用 UIAlertController
  • UIButton *btn = [UIButtonbuttonWithType:UIButtonTypeCustom];
  • UILabel *label = [[UILabelalloc] initWithFrame:CGRectMake(0,25, 265, 40)];
  • UIView *v = [[UIViewalloc] initWithFrame:CGRectMake(0,0, 200, 75)];
  • UIAlertView *alertView = [[UIAlertViewalloc] initWithTitle:nilmessage:nildelegate:nilcancelButtonTitle:NSLocalizedString(@"确定",nil otherButtonTitles: nil];
  • [alertView setValue:vforKey:@"accessoryView"];

7> 控制器生命周期方法调用的顺序来实现代码避免线程堵塞
  • - (void)viewDidLoad
  • {
  •     [super viewDidLoad];
  • }
8> 如何实时接收UI界面所需要的数据来刷新界面准确来说应该是改数据了调用setter方法加载新的数据刷新界面[tableView reloadData];
  • NSTimer *timer = [[NSTimeralloc] init]; 来实现也可以但是比较愚蠢

9> UIButton 有状态区分所有再使用和重写setter&getter方法的时候要注意
  • UIButton *btn = [[UIButtonalloc]init];
  • [btn setTitle:NSLocalizedString(@"测试",nilforState:UIControlStateNormal];
  • NSString *normalStr = [btncurrentTitle];

10> 研究Quartz 2D绘图技术数据实时更新和绘图
  • /**
  •  *  重写setter方法调用[self setNeedsDisplay];
  •  */
  • - (void)setNeedsDisplay
  • {
  •     [self setNeedsDisplay];
  • }
  • - (void)drawRect:(CGRect)rect
  • {
  •     // 一般在这里面写绘图的代码
  • }

11> 在自定义控件我们会考虑选择继承或者写分类 都拥有这个类本身的特性但是如果对于自定义的控件本身并没有多的拓展或者增加控件那么选择继承 但是如果这个类提供的控件已经不满足我们的需求那么我们选择写分类
  • /**
  •  *  目的是去掉父类在高亮时所做的操作
  •  */
  • - (void)setHighlighted:(BOOL)highlighted {}
  • #pragma mark - 覆盖父类的2个方法
  • #pragma mark 设置按钮标题的frame
  • - (CGRect)titleRectForContentRect:(CGRect)contentRect {
  •     CGFloat titleY = contentRect.size.height* ZZButtonImageRatio;
  •     CGFloat titleH = contentRect.size.height - titleY;
  •     CGFloat titleW = contentRect.size.width;
  •     return CGRectMake(0, titleY, titleW,  titleH);
  • }

  • #pragma mark 设置按钮图片的frame
  • - (CGRect)imageRectForContentRect:(CGRect)contentRect {
  •     CGFloat imageH = contentRect.size.height* ZZButtonImageRatio;
  •     CGFloat imageW = contentRect.size.width;
  •     return CGRectMake(0,0, imageW,  imageH);
  • }

12> 在控制器进行切换转场的时候有时候会出现阴影,这是由于色调不一致而导致,那么我们的做法是在控制器加载完毕的时候处理
  •  —> 对控制器生命周期的理解和掌握
  • - (void)viewDidLoad
  • {
  •     [super viewDidLoad];
  •     self.view.backgroundColor= [UIColor whiteColor];
  • }

13> 对MJ新特性界面原理的掌握后,然后完成封装的一套MVC原理更加面向开发的新特性框架

14> 在对 [ NSUserDefaults standardUserDefaults ]; 理解创建时候存储加载时候取出
  • 但是重难点:取出之后方法走几次是否实时显示那么该写在什么界面以及通过key存取什么就是什么一般用id 接收

15> iPhone 的屏幕比例

16> 在进行代码调试的时候 po 所需要的东西

17> 对注册界面的值进行约束以及恰当提示,其次完成注册界面回传值到登陆界面让用户完成直接登录通过NSUserDefault 进行存储和接收(难点:这个密码会进行md5加密所以在实现存储和取值时必须在md5加密之前实现存储)

18> 本地通知实现那么本地通知写在那里都是可以的之前为什么不出来本地通知呢?首先在本地通知的时候xcode6之前需要加载本地通知证书允许通知xcode实现了本地通知需要在 didFinishLaunchingWithOptions 中实现如下方法 :
  •  if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
  •         [application registerUserNotificationSettings:[UIUserNotificationSettingssettingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSoundcategories:nil]];
  •     }

19> 完成启动界面延迟加载
  • [NSThread sleepForTimeInterval:0.25];

20> Xcode->Product->Analyze(command+shift+B) 检查内存泄漏

21> Xcode插件管理

22> Xcode那些你不能错过的插件

23> 页面切换效果设置

24> UISwitch isOn属性和UIButton selected属性不一样 所以存储时候要注意
  • UISwitch 只能通过 UIControlEventValueChanged 来监听

25>  NSUserDefaults 存储对象 或者存储 bool int object 这之类的东西
  • 首先如何做即时存储那么存储的东西即时显示那么我们就要考虑
  •  0.控制器的生命周期
  •  1.存储所取需要的东西其次在存储和取的值之间相互转换问题
  •  2.存储通过什么key\keypath 存储取出时候需要什么取什么

26> 在输入文字 例如lable 或者button.titleLable.text  这样的设置的时候 numberOflines = 0 这样的操作时候换行 那么在AlertView 中文字 我们要实现换行功能也可以在文字中 手动加入\n 这样转译符号

27> 项目中我们可能 要设置这些 tag 因为你通过 NSUserDefaults 存储所以你必须合理设置和记住这些值  不然程序运行就行崩溃 当你改动tag 值必须要卸载程序 和清除缓存才能保证程序不崩溃 所以准确来说这是一个不太合理的设计模式

28>  @synthesize 合成语法
  • @代表“Objective-C”的标志,证明您正在使用Objective-C;
  • Objective-C语言关键词,@property@synthesize配对使用。
  • 功能:让编译好器自动编写一个与数据成员同名的方法声明来省去读写方法的声明。
  • http://blog.csdn.net/zhiganglet/article/details/7546333

29>  获取当前正在使用的语言版本(难点:例如我们根据正在使用语言设置相关的界面设置不同的界面例如中英文转换的时候UI界面不一致可以根据正在使用语言设置2个frame) 
  •     NSArray *languages = [NSLocale preferredLanguages];
  •     NSString *currentLanguage = [languages objectAtIndex:0];
  •     NSLog ( @"%@" , currentLanguage);

  •     if ([currentLanguage isEqualToString:@"zh-Hans"]) {
  •         self.textLabel.text= music.numberSound;
  •         self.detailTextLabel.text= music.name;
  •     } else if ([currentLanguage isEqualToString:@"en"]) {
  •         self.textLabel.text= music.numberSoundE;
  •         self.detailTextLabel.text= music.nameE;
  •     }

30> 改项目名称和软件名称
  • 单击项目(改名称)—>Rename—>enable—>contiue
  • Manage Schemes..—> 单击名称—> 点空白—>ok 

31> 我们在使用 SQL 的时候我们应该手动导入 SQL3 的框架FrameWork FMDB OC 的方式 装了 SQLite的C语言API
  • FMDB 三个主要的类:
  • FMDatabase —> 一个对象代表一个单独的SQLite数据库 (用来执行SQL语句)
  • FMResultSet —> 使用FMDatabase 执行查询后的结果集
  • FMDatabaseQueue —> 用于在多线程中执行多个查询或更新,它是线程安全的(即不会产生资源抢夺,死锁等情况)
  •     /**
  •      *  path 三种情况
  •      *  1.具体的文件路径:找到具体的文件路径,如果不存在自动创建
  •      *  2.空字符串@""nil的区别 @"" 还是一个对象
  •      *   >会在临时目录创建一个空的数据库
  •      *   >FMDatabase连接关闭时,数据库文件也会被删除
  •      *  3.nil: 会创建一个内存中的临时数据库,FMDatabase连接关闭时,数据库会被销毁
  •      */
  •     FMDatabase *db = [FMDatabase databaseWithPath:path];
  •     if (![db open]) {
  •         NSLog(@"数据库打开失败!!!");
  •     }
  • 数据库操作:我们做移动端开发,打开数据库后就长期打开不要轻易关闭,而服务器端则不一样,则是使用的时候就打开,使用完毕就关闭,下次使用再次打开!既然要长期打开 我们就应该更加面向对象用OC的语法 用一个strong 引用就行

  • 目前服务器端大的数据库Oracle dbq 而MySQL比较轻量级
  • http://zhidao.baidu.com/link?url=Ldq-FbKLDec-oltXrbgY2YXUdlJfg5_UXECrU5LZ-gnURhjsEOOKfMuvFWWZY8En_57qM9QbFkZkeutiVoQYBQXMyzNcw5A2yvhThZ_7ucq

  • 数据库是关系型数据库:意为表1、表2的相互关系 而对象型则直接扔对象进去 作为一张表:肯定有主键 id 而且是自动增长的这是规范
  • http://blog.csdn.net/robinjwong/article/details/18502195

32> Show the Breakpoint navigator 全局断点 [—]> 

33> 使用kvc 和kvo 的区别kvc 键值编码 kvo 则可以监听任何对象的事件 使用kvo 的时候 一定要调用dealloc 析构方法来手动释放 避免野指针错误

34> 这个是蓝牙开发那么如何保持蓝牙在后台一直运行呢?
  • (难点:Capabilities —> Background Modes —> ON —> Bluetooth 选项)

35> 开发中中心

36> 数据缓存思想 :例新浪微博
  • —> 存模型:IWStatus—>NSData以blob形式存储  [NSKeyArchiver archivedDataWithrootObject:id];
  • —>直接存Json[@“Statues”]—>对应微博对象    .. 必须遵守NSCoding 协议

37>  bolck 全局变量 写在外面 不能使用点语法 一次创建写在initialize里面
  • @implementation ZZStatusCacheTool
  • static FMDatabaseQueue *_queue; // 一般区分全局变量和局部变量全局变量加上 _
  • @end

38> 获取沙盒中的文件名
  • NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) lastObject] stringByAppendingPathComponent:@"statuses.sqlite"];

39> FMDB 增删查改 然后 事务和多线程中FMDB的使用
  • 要使用  @property(nonatomic,strong) FMDatabaseQueue *queue;
  • // 经典案例:银行存款俩个人同时操作一个账号 
  • // 事务的概念:银行 一系列操作如果中间某项出错那么回滚
  • #import “ZZViewController.h"
  • #import "FMDB.h"

  • @interface ZZViewController ()
  • @property (nonatomic,strong) FMDatabaseQueue *queue;
  • - (IBAction)insert;
  • - (IBAction)update;
  • - (IBAction)delete;
  • - (IBAction)query;
  • @end

  • @implementation ZZViewController

  • - (void)viewDidLoad
  • {
  •     [super viewDidLoad];
  •    
  •     // 0.获得沙盒中的数据库文件名
  •     NSString *filename = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) lastObject] stringByAppendingPathComponent:@"student.sqlite"];
  •    
  •     // 1.创建数据库队列
  •     self.queue= [FMDatabaseQueuedatabaseQueueWithPath:filename];
  •    
  •     // 2.创表
  •     [self.queueinDatabase:^(FMDatabase *db) {
  •         BOOL result = [db executeUpdate:@"create table if not exists t_student (id integer primary key autoincrement, name text, age integer);"];
  •        
  •         if (result) {
  •             NSLog(@"创表成功");
  •         } else {
  •             NSLog(@"创表失败");
  •         }
  •     }];
  • }

  • - (IBAction)insert
  • {
  •     [self.queueinDatabase:^(FMDatabase *db) {
  •         for (int i = 0; i<40; i++) {
  •             NSString*name = [NSString stringWithFormat:@"rose-%d",arc4random() % 1000];
  •             NSNumber*age = @(arc4random() %100 + 1);
  •             [db executeUpdate:@"insert into t_student (name, age) values (?, ?);", name, age];
  •         }
  •     }];
  • }

  • - (IBAction)update
  • {
  •     [self.queueinDatabase:^(FMDatabase *db) {
  •         // 开启事务
  • //        [db executeUpdate:@"begin transaction;"];
  • //        [db beginTransaction];
  •        
  •         [db executeUpdate:@"update t_student set age = ? where name = ?;",@20, @"jack"];
  •         [db executeUpdate:@"update t_student set age = ? where name = ?;",@20, @"jack"];
  •        
  •        
  • //        if (发现情况不对){
  • //            // 回滚事务
  • //            [db rollback];
  • ////            [db executeUpdate:@"rollback transaction;"];
  • //        }
  •        
  •        
  •         [db executeUpdate:@"update t_student set age = ? where name = ?;",@20, @"jack"];
  •        
  •         // 提交事务
  • //        [db commit];
  • //        [db executeUpdate:@"commit transaction;"];
  •     }];
  • }

  • - (IBAction)delete
  • {
  •     [self.queueinTransaction:^(FMDatabase*db, BOOL *rollback) {
  •         [db executeUpdate:@"update t_student set age = ? where name = ?;",@20, @"jack"];
  •         [db executeUpdate:@"update t_student set age = ? where name = ?;",@20, @"jack"];
  •        
  • //        if (发现情况不对){
  • //            // 回滚事务
  • //            *rollback = YES;
  • //        }
  •     }];
  • }

  • - (IBAction)query
  • {
  •     [self.queueinDatabase:^(FMDatabase *db) {
  •         // 1.查询数据
  •         FMResultSet*rs = [db executeQuery:@"select * from t_student where age > ?;",@50];
  •        
  •         // 2.遍历结果集
  •         while(rs.next) {
  •             intID = [rs intForColumn:@"id"];
  •             NSString*name = [rs stringForColumn:@"name"];
  •             intage = [rs intForColumn:@"age"];
  •            
  •             NSLog(@"%d %@ %d", ID, name, age);
  •         }
  •     }];
  • }

40> 点击模拟器之后进行还原设置(当模拟器无法上网的时候我们可以选择还原设置)

41> BOOL 类型的定义 在一些 block 中我们起初定义 BOOL 的值然后在block中回调这个方法  * BOOL 指向 bool类型的指针 如果我们要停止这个遍历那么让* BOOL  = YES; (算是运行时的一个机制)

42> 我们想要将对象直接存到一个文件路径中的时候会出现问题因为存对象我们必须遵守<NSCoding>协议
  • #import "MJExtension.h" 
  • MJCodingImplementation (又一强大的MJ语法)
  • - (void)encode:(NSCoder *)encoder
  • {
  • //    [self encode:encoder];
  •    /**
  •      *  归档所有对象 相当于调用上面代码 封装完毕
  •      *
  •      *  @param ivar 遍历所有要存储的对象
  •      *  @param stop BOOL类型的定义在一些block中我们起初定义BOOL的值然后在block中回调这个方法
  •   *  BOOL 指向 bool类型的指针如果我们要停止这个遍历           
  •      *  那么让* BOOL  = YES; (算是运行时的一个机制)
  •      */
  •     [self enumerateIvarsWithBlock:^(MJIvar*ivar, BOOL *stop) {
  •         [encoder encodeObject:ivar.valueforKey:ivar.propertyName];
  •     }];
  • }

  • - (id)initWithCoder:(NSCoder *)decoder
  • {
  • //    [self decode:decoder];

  •     if (self = [superinit]) {
  •         [selfenumerateIvarsWithBlock:^(MJIvar*ivar, BOOL *stop) {
  •             ivar.value= [decoder decodeObjectForKey:ivar.propertyName];
  •         }];
  •     }
  •     return self;
  • }

43> Xcode 6增加pch文件  

44> 苹果开发者中心我们登陆时候显示问题 ANNOUNCEMENT: Updated Program License Agreement 解决办法

45> 苹果开发者账号注册流程

46> 关于 Xcode 配置窗口配置文件, Xcode 真机调试出现如下问题 :0xE8008018

47> 调试过程中出现的小bug无法正常运行进行Debug

48> 事件传递者方法如何知道你点击是那个 view
  • /**
  •  *  - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;   // recursively calls - pointInside:withEvent:. point is in the receiver's coordinate system
  •     - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;   // default returns YES if point is in bounds
  •  *
  •  *  事件传递者方法
  •  */

49> UISplitViewController 的简单使用

50> 谷歌浏览器自动拦截广告插件


52> 在一个控件传递他的 userInteractionEnabled 属性时候,如果作为代理已经将这个事件传递出去那么你无论何时监听它的事件改变都没有用,只有将这个按钮的状态传出去根据状态来显示这个按钮是否可以被点击

53> Xcode 插件网址都是对的 每次更新Xcode 插件也会更新那么你依旧点击网址重新更新改info.plist中的一个item就行

54> iOS 开发小技巧之提示音播放与震动

55> 通知中心使用方法

56> iOS 开发系列— 通知与消息机制 1>本地通知 2>推送通知 3>iOS开发证书、秘钥 4>通知中心

57>  Xcode 快捷键大全

58>  Xcode 数据显示在控制台

59>  UISwitch 用法小技巧
  • /**
  •  *  实时显示开关的记录并且根据调用layer动画
  •  *  UISwitch 技巧
  •  *  1> 监听UISwitch 只能够是 UIControlEventValueChanged因为它只有YES\NO属性
  •  *  2> 实时设置UISwitch 开关属性的时候只能调用self.dismissSwitch.on(不能调用isOn)
  •  */

60>  素材网址 

61> iOS9 https
  • <key>NSAppTransportSecurity</key>
  • <dict>
  •     <key>NSAllowsArbitraryLoads</key>
  •     <true/>
  • </dict>

62> VFL <==> Visual Format Language  苹果神器的开发者开发的神奇语言 使用NSLayoutConstraint 代码约束

63> 提取代码的时候
  •  1.如何提取:先把程序跑起来,你想要那块例如Xib\纯代码你想要那一块就去找一块例如找一个View所属的Class那么就去对应的控制     器去研究
  •  2.你需要什么功能直接猜,注释直接了当是什么就搬什么,搬过来就运行缺什么拷什么
  •  3.到最后才需要研究代码如何那么连蒙带猜研究别人的代码!

64> 移动网络应用 = 良好的 UI + 良好的用户体验 + 实时更新的数据 ( 新闻 \ 视频\音乐\LBS\电商\社交)

65> 字典的常用使用方法和数据处理

66> 如何把一个字典格式的字符串转换成字典

67>  将本地数据库东西上传到服务器

68> 如何将本地的MYSQL数据库上传到服务器

69> 做的项目涉及到服务器,将项目上传到服务器上

70>  网页数据库上传到服务器

71> Xcode 升级 插件失效快速解决方式 命令行解决所有Xcode插件问题  屌屌屌

72> 如何不用手动添加导航栏上面的按钮 用方法来实现覆盖
  • UIImage * leftImg = [[UIImageimageNamed:@"HomeLeft_Icon"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
  • self.navigationItem.leftBarButtonItem= [[UIBarButtonItemalloc] initWithImage:leftImg style:UIBarButtonItemStyleDonetarget:selfaction:@selector(go)];

73> NSMutableArray 转成 NSData 类型

74> 日期和 NSCalendar / NSDateFormatter / NSString 相互转换的用法

75> 如何设置UIButton 按钮上面更多的属性

76> 蓝牙广播模式建立通信过程

77> AFNetWorking 网络请求报错的原因添加方法

78> TableView 中增加和删减的方法以及详细解决

79> 即时通讯系统

80> 在cell 中添加东西 不一定是要 [cell. contentView addSubview : nil ];
  • 如添加开关或者箭头或者别的按钮之类的控件那么可以自定义控件懒加载 然后 cell.accessoryView= self.switchView;这样加载;

81> iOS APP应用对接微信SDK

82> 第三方分享平台集成SDK

83> Xcode如何去掉 iOS 开发 implicit conversion loses integer precision : NSInteger 这样的警告 64位和32位的区别

84> 懒加载的作用只要为空就创建\并且屏蔽了创建的过程而且封装了

85> clang: error: linker command failed with exit code 1 (use -v to see invocation)

86> 在多人开发中使用svn/git同步代码的时候 有时候代码带不开报警告

87> Could not find Developer Disk Image 在Xcode真机调试的时候 是手机系统和Xcode 最高支持不匹配!

88> The file “Eknot” couldn’t be opened because you don’t have permission to view it 这种问题的解决方案

89> VFL这门强大的约束语言 command + shift + 0 查看苹果官方API 在VFL中可以帮我们实现大部分的约束的但是设计到乘除的那么我们就需要用到  NSLayoutConstraint 来添加约束!

90> UITableView他的流程是你设置数据源 然后你成为他的数据源并且遵守协议 实现方法 那么首先确定有多少组 然后他就会调几次 对于cell中 他也会根据你设置的数据来自动调用几次!!!

91> UITableView plain/group 样式 plain样式头部标题当被顶上去的时候会自动留下但是group就不行;

92> TableView 默认行高 44 要设置2种方式 rowHeight/方法返回 iOS 6 分割线 从头像全程画  iOS 7只从Label 开始画

93> TableViewCell 必须掌握 首先设置右边的 样式 cell.accessoryType / 这是取系统的样式 有时候不够用要设置自己的view 那么用 cell.accessoryView / 然后自己定义样子  cell.backgroudView cell.selectedBackgroudView 先创建view 再设置
cell的backgroudView 优先级 > backgroudColor 

94>
Pasted Graphic.tiff

95> cell 的循环利用 每当有一个cell进入我们的视野范围内就会调用?那么创建过的呢?所以即使你显示的内容一样但是每次都在alloc 每次都在创建!牵扯到覆盖cell的数据和状态的代码 一定要写在外面~ static NSString *ID = @“A”; 这是C语言的特性即使你调一千次一万次也只会分配一次内存空间(只初始化一次)! 这个ID只在cell内部循环利用那么就没必要写成宏可以让别人都可以访问;到处都要用 多处都需要用的时候写成宏 虽然你在cell中不用缓存池中取那么当你的cell消失屏幕的时候这个cell会自动消失但是你不停的滚动那么不停的销毁不停的创建是非常消耗性能!

96> [self.groups valueForKey:@“title”] 这个方法这么写会报错 我们不能直接取,因为self.groups 没有title属性 是数组中的元素有title属性,所以我们要间接取[self.groups valueForKeyPath:@“title”];

97> 模型中嵌套模型这个需要深刻的理解! 以及KVC用法;

98> iOS ipa 怎么防止黑客攻击和反编译

99> tableView 首先didSelect 选中 然后didDeselect 取消选中 那么在cell之间切换的时候会发生俩件事那么就知道什么方法调用的顺序;

100>  UIAlertView *alert = [[ UIAlertView alloc ] initWithTitle : nil message : nil delegate : nil cancelButtonTitle : nil otherButtonTitles : nil , nil];
    [alert show ];
  • typedef NS_ENUM(NSInteger, UIAlertViewStyle) {
  •     UIAlertViewStyleDefault = 0,
  •     UIAlertViewStyleSecureTextInput,
  •     UIAlertViewStylePlainTextInput,
  •     UIAlertViewStyleLoginAndPasswordInput
  • } __TVOS_PROHIBITED;

101> 如何把要显示的文字显示在文本输入框里面呢?
  • [alert textFieldAtIndex:0].text = hero.name; ? 这里会判断有几个文本输出框 根据index 标号来判断

102> 有些时候在开发中我们要判断 例如 if (self …..) {  // 这样的代码
}  所以我们尽量直接判断如果不是就return 是的才执行后面的代码!

103> tableView中我们做数据刷新 首先是要改模型数据 而不是拿到cell中的单独的元素进行修改 然后刷新数据也就是重新加载模型数据;

104> 要将某个俩个不相关方法中某个值传递到某个方法中 写一个全局变量 然后在拿到的位置赋值 在需要的位置显示能够拿到来显示!

105> tableVie 刷新本质就是cellForRow这个方法的进入视野和离开视野重新加载模型属性的过程 那么我们就是让系统自己去调用这个方法 [self.tableView reloadData]; 重新给数据源发消息 重新调用数据源的相应方法 告诉数据源重新加载数据 显示怎么样的cell
  • #pragma mark - 代理方法
  • - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  • {
  •     // 1.取得被点击这行对应的模型
  •     MJHero *hero = self.heros[indexPath.row];
  •    
  •     // 弹框
  •     UIAlertView*alert = [[UIAlertViewalloc] initWithTitle:@"数据展示"message:nildelegate:selfcancelButtonTitle:@"取消"otherButtonTitles:@"确定",nil];
  •    
  •     // 设置对话框的类型
  •     alert.alertViewStyle= UIAlertViewStylePlainTextInput;
  •    
  •     // 取得唯一的那个文本框,显示英雄的名称
  •     [alert textFieldAtIndex:0].text= hero.name;
  •    
  •     [alert show];
  •    
  •     // 绑定行号到alertView
  •     alert.tag= indexPath.row;
  • }

  • #pragma mark - alertView的代理方法
  • /**
  •  *  点击了alertView上面的按钮就会调用这个方法
  •  *
  •  *  @param buttonIndex 按钮的索引,0开始
  •  */
  • - (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
  • {
  •     if (buttonIndex == 0)return;
  •    
  •     // 按钮的索引肯定不是0
  •    
  •     // 1.取得文本框最后的文字
  •     NSString*name = [alertView textFieldAtIndex:0].text;
  • //    int row = alertView.tag;
  • //    NSIndexPath *path = [NSIndexPath indexPathForRow:row inSection:0];
  • //    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:path];
  • //    cell.textLabel.text = name;
  •    
  •     // 2.修改模型数据
  •     int row = alertView.tag;
  •    ZZHero*hero = self.heros[row];
  •     hero.name = name;
  •    
  •     // 3.告诉tableView重新加载模型数据
  •     // reloadData : tableView会向数据源重新请求数据
  •     // 重新调用数据源的相应方法取得数据
  •     // 重新调用数据源的tableView:numberOfRowsInSection:获得行数
  •     // 重新调用数据源的tableView:cellForRowAtIndexPath:得知每一行显示怎样的cell
  •     // 全部刷新
  • //    [self.tableView reloadData];
  •    
  •     // 局部刷新
  •     NSIndexPath*path = [NSIndexPathindexPathForRow:rowinSection:0];
  •     [self.tableViewreloadRowsAtIndexPaths:@[path]withRowAnimation:UITableViewRowAnimationBottom];
  • }

106> 自定义cell/通过xib来描述cell 往cell里面添加字控件默认都是添加到contentView上面
  • 因为contentView是cell内部的子控件打印内存地址 在为cell添加属性的时候不能覆盖系统自带的cell属性3个基本属性!

107> tableViewFooterView & tableViewHeaderView 头部和尾部 设置 只需要设置高度 然后往上面设置东西!

108> iOS中加载资源包 UINib *nib = [UINib nibWithNibName: bundle:] 加载xib的另外一种方式 我们项目中所有的资源都是放在一个资源中[NSBundle mainBundle] 但是我们需要传这个参数的都可以传nil 默认就是mainBundle

109> 通过xib\nib 创建的控件显示在view中我们有时候要用到他们做一些事情 第一种做法绑定tag 然后 [view viewWithTag:] 取出来

110> 我们要在view中执行controller 的方法 首先让view拥有controller这个属性然后在对应的controller里面设置接着在view中用

111> 多久之后执行block里面的代码
  •  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> *NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  •         <#code to be executed after a specified delay#>
  •     });

112> MVC的思想view绝对不能直接访问控制器的属性这样耦合性就很强view离不开控制器!控制器是用来加载模型显示到view上面去!view 和 model 可以重用但是控制器绝对不可以!谁想要搞一些事情谁就应该搞一个代理属性 谁监听谁的操作他就是他的代理

113> iOS中字典与json格式相互转换

114> JSONKit 框架要使用非arc 编译

115> 如果通过代码创建控件那么任何控件都可以添加到其他控件上面去
  • 但是冲过storyboard/xib 不可能把其他控件添加到UIImageView里面去所以代码是万能的

116> 按钮UIButton 设置图片 如果设置background 那么你的按钮背景有多宽多高你的图片就会被扯的有多宽多高 但是如果设置为UIImage 你的图片有多少它就只会有多少!

117> self . view . window  <==> [ UIApplication sharedApplication ]. keyWindow  <==>  self . view . superview

118> [UIWindow alloc] init] 这个是局部变量!创建完这行代码过后就会被销毁所以在有些变量要用指针指向它!

119> 在iOS6和7只有主窗口才能输入东西,次窗口是不能输出东西 然后通过UIApplication 获得主窗口和窗口列表!!

120>  
  • /**
  •  *  只要实现了这个方法它会先看你这个方法是怎么实现它就怎么加载view,不会去管xib\storyboard创建的文件,如果没有才会
  •   *    去看有没有xib\storyboard
  •  *  自己来自定义view\自己决定自己的view是什么样式的
  •  *  控制器view的延迟加载
  •  *  控制器的view是延迟加载的:用到时再加载
  •  *  可以用isViewLoaded方法判断一个UIViewControllerview是否已经被加载
  •  *  控制器的view加载完毕就会调用viewDidLoad方法
  •  */
  • - (void)loadView
  • {
  •     self.view= [[UITableView alloc] init]; // 如果这里写空或者不写那么用到就来创建实现loadView方法所以会一直加载
  •     self.view.backgroundColor= [UIColor redColor];
  • }

121> 通过xib创建的view File’s Owner 需要自己手动去添改 然后连线view

122> 显示在导航控制器上面的永远是栈顶控制器 中间的或者其它的 永远没有机会显示!系统创建的back 返回键是移除栈顶控制器!

123> 在导航控制器中当前界面显示什么样导航条由当前控制器决定即栈顶控制器决定,但是返回的item由上一个控制器决定返回的文字以及它的样式;
  • self.navigationItem.backBarButtonItem= [[UIBarButtonItemalloc] initWithTitle:@"返回"style:UIBarButtonSystemItemDonetarget:nilaction:nil];

124> 程序启动到完全显示是需要一个过程的 只有程序获得了焦点: 所有的控件才能接收触摸事件 导航控制器中的线往回拖是重新创建一个新的控制器 根据导航控制器栈的特点来判断!

125> 收到内存警告 首先是代理先知道 然后通知显示在眼前的控制器清理资源!是指暂时没有显示在窗口上的view很可能被销毁

126> 监听一些控件的方法 add target / delegate / 通知 必须想到这三种方法

127> storyboard中拖线如果从左边某一个按钮直接拖到右边 那么拦截的机会都没有
  • 所以我们要从控制器底部拖线过去Segue的2大类型 自动型和手动型 控制器顺传递数据 根据segue可以获得标识 来源控制器 目标控制器 然后设置属性 即传递参数

128> 代理不止在view中有,在controller 中也可以实现代理 来实现数据传递 那么记住代理的原则 A 发生某些事 向告诉B 那么用代理就很直接!所以记住原则!

129> UITextField 控件所有的属性

130> 封装cell 我们在些[ZZTableViewCell alloc ] init] 他这么写他会优先去缓存池中根据标识取这样的然后刻一个模版出来如果没有就去storyboard 中创建 那么只要是通过storyboard 中创建的cell 他不会调用 init 开头的方法 initWithCoder 除外! 会调用awakeFromNib 这个方法!

131> 数据存储我们plist存储 write to file  偏好设置存储 NSUserDefaults  存对象encoder 子类继承父类那么注意了先调用父类的方法然后进行存储!

132>  tableView 的刷新
  • 1> 数据刷新的总体步骤
  • * 修改模型数据
  • * 刷新表格(刷新界面)

  • 2> 刷新表格(刷新界面)的方法
  • * 全局刷新(每一行都会重新刷新)
  • - (void)reloadData;

  • * 局部刷新(使用前提:刷新前后, 模型数据的个数不变)
  • - (void)reloadRows:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;

  • * 局部删除(使用前提:模型数据减少的个数 == indexPaths的长度)
  • - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;

133>  @property 属性的用法
  • weak(assign) :  代理\UI控件
  • strong(retain) : 其他对象(除代理\UI控件\字符串以外的对象)
  • copy : 字符串
  • assign : 非对象类型(基本数据类型int\float\BOOL\枚举\结构体)

134> tableView自带的滑动删除的功能
  • #pragma mark - tableView的代理方法
  • /**
  •  *  如果实现了这个方法,就自动实现了滑动删除的功能
  •  *  点击了删除按钮就会调用
  •  *  提交了一个编辑操作就会调用(操作:删除\添加)
  •  *  @param editingStyle 编辑的行为
  •  *  @param indexPath    操作的行号
  •  */
  • - (void)tableView:(UITableView*)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
  • {
  •     if (editingStyle == UITableViewCellEditingStyleDelete) {// 提交的是删除操作
  •         // 1.删除模型数据
  •         [self.contactsremoveObjectAtIndex:indexPath.row];
  •        
  •         // 2.刷新表格
  •         // 局部刷新某些行(使用前提:模型数据的行数不变)
  •         [self.tableViewdeleteRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationTop];
  •        
  •         // 3.归档
  •         [NSKeyedArchiverarchiveRootObject:self.contactstoFile:MJContactsFilepath];
  •     } else if (editingStyle == UITableViewCellEditingStyleInsert) {
  •         // 1.修改模型数据
  •         ZZContact *contact = [[MJContactalloc] init];
  •         contact.name= @"jack";
  •         contact.phone= @"10086";
  •         [self.contactsinsertObject:contactatIndex:indexPath.row+ 1];
  •        
  •         // 2.刷新表格
  •         NSIndexPath*nextPath = [NSIndexPathindexPathForRow:indexPath.row+ 1 inSection:0];
  •         [self.tableViewinsertRowsAtIndexPaths:@[nextPath]withRowAnimation:UITableViewRowAnimationBottom];
  • //        [self.tableView reloadData];
  •     }
  • }

  • - (void)deleteClick
  • {
  •     // tableView进入编辑状态
  •     [self.tableViewsetEditing:!self.tableView.isEditinganimated:YES];
  • //    self.tableView.editing = !self.tableView.isEditing;
  • }

135> 导航栏上面的item属性默认是nil 所以需要创建 但是tabbarItem 不是空所以设置属性不需要重新创建直接赋值就行 tabbar 上面的子控制器viewDidLoad 方法只会调一次 因为tabbar在那么控制器就在 所以不会被销毁!控制器的生命周期的方法必须掌握!

136> 移除tabbar 子控件的方法(一)
  • UITabBarController *tabbarVc = (UITabBarController*)self.window.rootViewController;
  • NSLog(@"%@",NSStringFromCGRect(tabbarVc.tabBar.frame));
  •    
  • for (UIView*child in tabbarVc.tabBar.subviews) {
  •    if ([child isKindOfClass:[UIImageViewclass]]) {
  •        [child removeFromSuperview];
  •     }
  • }

137> 移除tabbar 子控件的方法(二) 
  • [tabbarVc.tabBar.subviewsmakeObjectsPerformSelector:@selector(removeFromSuperview)];这是研究方法我们要会去摸索研究这些东西!
138>
  • //app进入后台:休眠不能接受事情(比如关闭)
  • /**
  •  *  app关闭的时候调用(一般情况下不会调用)那么我们配置这个程序的类型plist
  •  */
  • - (void)applicationWillTerminate:(UIApplication *)application
  • {
  •     NSLog(@"applicationWillTerminate");
  • }

139> 如果 tableViewController 是用静态单元格实现 那么把 UITableViewController 里面的数据源方法删掉否则东西就出不来

140> modal 模态窗口\任何控制器都能通过modal 出来 modal 就是弹框之后后面所有的控件都不能被点击 我们modal 出来的控制器 显示了 但是窗口的根控制器没有改变更没有被销毁!只是窗口的view被更换了换成了第二个!那么第二个控制器不会被销毁的原因是因为它被present 属性引用着 presentViewController 相互引用所有不会被销毁

141>  modal 出来的控制器最好包装一个导航控制器 但是在dismiss 时候我们因该让self.navgationController dismiss 但是只要是它的子控制器也可以!

142>   iOS 开发常用正则表达式 以及正则表达式解析

143>  block 传值以及定义block 和传参block

144> 日期格式和字符串相互转换

145> iOS开发中布局字控件 layoutSubviews研究

146> iOS开发中subViews的事件响应原理深究

147> iOS开发中 stong 和 weak 的解释
  • stong :默认情况下任何指针都是强指针
  • weak : 使用__weak修饰的指针(明显申明的)
  • Person *p = [Person alloc] init];  // 在内存的表现是 右边分配内存给person 对象 而左边则是一个指针P引用着person对象
  • // ARC 的判断准则: 只要没有任何强指针指向对象,这个对象就会被销毁  Person *p  这个是局部变量 是有范围的(所以要注意创建的局部变量的范围即{});
  • 人在狗在的例子: 为什么模型属性普通对象要用stong 我们知道在@property 这个方法的时候系统会自动生成_dog 的属性 他也有一个指针是强是弱取决于你申明的时候写的strong 还是weak 所以我们创建dog 对象 然后赋值给人的dog 属性的时候也就是_dog 也指向那块区域这样就保证了 人在狗在! 例 : dog = nil ;这样的写法是指将指针清空不指向任何对象!
  • 俩个对象之间循环引用必须有一个对象是弱指针 相互引用即使执行完了main 函数也不会被销毁 画图分析一下就会懂!分析原理!

148> 为什么UI 控件要用弱指针 : 其实用strong 也可以但是没有必要 如图:
  • 这样我们就保证了控制器在这个UIButton 属性就在 所以UI控件用strong 和 weak 已经无所谓了 但是weak 在不用的时候会自动销毁
Pasted Graphic_1.tiff


149> 一般控件的代理都是控制器那么如上图所以代理要用weak 如果用stong 那么谁也别想死

150> 自定义tabar你要拿到tabar做事情那么UITabbarController你就必须自定义如论通过storyboard 创建还是代码创建你都必须自定义

151> UIButton状态
  • /**
  •  normal : 普通状态
  •  highlighted : 高亮(用户长按的时候达到这个状态)
  •  disable : enabled = NO
  •  selected :  selected = YES
  •  */

152> init 方法 —> initWithFrame: 方法  Xcode 系统生成的方法都会很有用的 例如drawRect:

153> 各种封装的思想要考虑后面的扩展性 控制器死的惨不惨 封装的思想那么就必须掌握 谁最清楚这些事情那么他就处理这些事情 如何交给他 可能直接 提供方法 可能间接 代理\block 各种方法去实现 专供思维!

154> 身为程序员我们应该学会去偷懒:要去想要用最少的时间实现那个功能,用最精简的方式实现功能,不然要我们程序员干嘛!所以我们应该这样去思考问题!

155> 所有的对象都有这个方法 系统在第一次使用这个类的时候就会调用 那么只设置一次的代码我们就应该学会在这里设置
  • + (void)initialize
  • {
  •    
  • }

156> deployment Target 目标测试到系统版本至少为多少的

157> 很多应用程序在程序运行的时候状态栏隐藏 启动完毕了状态栏再次出现

屏幕快照 2016-05-03 下午3.04.25.png

158> 美工给的icon图标已经进行渲染了 我们要告诉他不需要在对我们的图片进行渲染 (取消毛玻璃效果)
屏幕快照 2016-05-03 下午3.04.54 1.png

159> UIBarButtonItem 很强大里面可以包装任何东西 那么有时候我们需要通过 storyboard/xib 来拖东西的时候直接拖我们需要的就行

160> 要改写父类的实现那么我们就必须改写父类的方法 继承\重写 2步走

161> 在写方法的时候我们运行Xcode 点了某一个按钮然后弹回Xcode 过了一会儿才报错 就是进入死循环了

162> 从文件中解析一个对象的时候就会调用这个方法 所以从xib\storyboard 中创建 我们在initWithCoder: 里面初始化最可靠但是我们在通过代码创建的时候不会调用这个方法 \ awakeFromNib 这个方法当一个对象从xib或者storyboard中加载完毕后,就会调用一次

163> 条件编译 : #import <Avali…..h>
#ifdef __IPHONE_7_0
#endif

164> iOS6 —> iOS7 控制器的view的巨大转变原因 self.edgesForExtendedLaout view的拓展 那么有时候我们在适配或者自定义view 的时候不需要拓展那么这就可以实现了 例如 : 某些侧滑 、某些弹框view

165> 我们运行程序有些时候上面一部分和下面一部分不显示出来那么就是启动图片的问题启动图片都只有那么大那么程序自然只有那么大 改json文件就行了 自己研究 storyboard和xib 适配或者拖东西 autoLayout 属性问题 优先考虑 3.5inch ->4.0inch 屏幕的改变

166> 在storyboard中我们要进行拉伸第一UIImage 的分类 第二在storyboard 中只有UIImageView 才有拉伸的属性 按钮的样式 长按 不会变成设置的高亮状态 那么我们就要注意按钮的样式

167> 导航栏上面的样式 第一种 UINavigationBar 和 UIBarButtonItem 设置导航栏上面的属性和样式 看iOS 过度指南  UIBarButtonItem 在连线的时候传递参数只有俩种选择要么传真实类型要么传id 那么我们自己写个方法连回storyboard就行

168> 字符串转类名 : (我们配着plist的时候可以这么做)
  • Class c = NSClassFromString(str);
  • UIViewController *vc = [c alloc] init];

169> MVC 改模型就改界面 改模型就改一切 MVC的思想必须牢牢掌握还有明白其中的原理以及特殊的情况

170> block 的作用就是用来保存一段代码用来回调、理解和运用好block 和C语言的函数相比较 函数的缺点我们之前写好的是什么后面就是什么函数是死的只能是全局变量你不在mian函数里面调用那么就永远不会调用 所以block出现了可以是局部变量也可以是全局变量

171> UICollectionViewController —>和UITableViewController 很像 数据源代理 collectionView 的分组概念:
  • 首先和tableView 一样 他的每一个格子都是一个collectionViewCell 然后他的排布取决于自己的宽度和collectionView的宽度其次他的分组我们也可以去定义 : 然后他的记录通过 index path : section 、item(这一组第几个)  但是我们在写自定义cell方法的时候并没有通过标识来创建: 那么我们就该换思路换想法 :他首先是在viewDidLoad中注册用什么样的cell(如果通过xib创建那么注意几个方法) 和什么样的标识告诉collectionView将来创建怎样的cell 如果没有就照着这个模子给我创建 所以我们不需要去缓存池判断他会自己创建然后返回给我们 
  • 你直接alloc init 会报错:我们如何布局取决于
  • UICollectionViewLayout布局对象UICollectionViewFlowLayout流水布局什么是流水布局就是每个格子随着view的宽度改变会自动流动去对应的位置 (瀑布流要自定义布局)
  • 布局这个东西控制我们的格子大小和格子以什么方式排布
  • /**
  •  UICollectionView must be initialized with a non-nil layout parameter
  •  
  •  必须用一个非nillayout参数来初始化UICollectionView
  •  */

172> KVC 致命的缺点在字典属性里面的key 不存在对应的模型属性的时候直接报错

173> 有些时候我们加载的view是直接的一层 即我们自定义的view 我们loadView 里面去写我们self.view 的类型就ok

174>  OC : 编译型语言有一行出错整个编译就不过 ;  JavaScript:解析型语言 解析一行运行一行 所以后面有错的他解析道前面后面相当于没有;

175>  在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并且处理事件;我们称之为”响应者对象”;
你想监听view内部的触摸事件必须自定义view然后覆盖系统有的方法

176>  一个完整的触摸过程: touchesBegan —> touchesMoved —> toucherEnded (一个专业的触摸) 任何view默认情况下都不支持多点触碰(改多点触碰)当用户用一根手指触摸屏幕时,会创建一个与手指相关联的UITouch对象
  • UITouch的作用:
  • 保存着跟手指相关的信息:比如触摸的位置、时间、阶段 (能记录手指当前位置也能或者手指上一个位置)
  • 当手指移动时、系统会更新同一个UITouch对象,使之能够一直保存该手指在的触摸位置
  • 当手指离开屏幕时,系统会销毁相应的UITouch对象
  • 他的属性我们能拿到触摸时所处的窗口(UIWindow)、触摸时所在视图(UIView)、短时间内按屏幕的次数、触摸变化时间、当前触摸事件所处的状态
  • UIEvent对象:(事件对象,记录事件产生的时刻和类型)
  • 事件类型、事件产生的时间还可以获得某个view上面的触摸对象
屏幕快照 2016-05-04 下午3.18.43.png

177> 关于数组和NSSet的区别
  • NSArray: (有序的)
  • NSSet: (无序的)都算是集合

178> 证书问题 那么我们按着官方文档的步骤走是没有任何问题的!其次因为证书问题经常报的错误
  • http://www.jianshu.com/p/b10680a32d35
  • 其次各种查法我们要学会去调试 还有手机上有已经销毁的程序我们要先卸载手机上的应用程序其次才能调试
  • I had this problem with an iPhone app, and fixed it using the following steps.
  • With your device connected, and Xcode open, select Window->Devices
  • In the left tab of the window that pops up, select your problem device
  • In the detail panel on the right, remove the offending app from the "Installed Apps" list.
  •  remove the offending app from the "Installed Apps" list.

179> 字符串截取的相应的方法

180> KVO 基本方法和使用

181> 我们自定义view时候 我目前一般都是继承UIView 然后从写方法在layoutSubviews 布局 但是有时候用for 循环加载控件那么你的子控件布局就会出现大问题 那么我们可以避免这样的初始化 我们通过给这个自定义的view 传递模型来写初始化的代码这样也省下很多事!不同的思想不同的思路!

182> 设置tableView backgroundColor\backgroundView view 的优先级是大于color的所以我们设置的时候要先清空 view 其次这种情况是在group模式下在存在 但是我们最好都设置nil

183>  cell是tableView的子控件所以我们要重写cell的frame 你在cell初始化的时候去写不会有作用 它由tableView决定所以我们要在合理的位置设置数据 iOS 6 cell也是屏幕的长度 但是cell是在contentView中所有会有间距 不管谁修改cell的frame 肯定是调用cell.frame 即setter方法 所以我们拦截这个操作 重新设置frame之后在交给父类去处理 这样我们就能改变
  • - (void)setFrame:(CGRect)frame
  • {
  •     // 重新布局的代码
  •    
  •     [super setFrame:frame];
  • }

184>  block循环引用因为block本身就是强指针,尤其在item中我们调用了block那么我们必须要先把block引用的对象拿出来变成弱指针然后在block中进行使用
  • __unsafe_unretained ZZUserSettingViewController *selfVc = self;
  • __unsafe_unretained typeof(self) selfVc =self;
  • __weak typeof(self) selfVc =self; // self <==> ZZUserSettingViewController * 类型 weak作用更强大

185> autoLayout 和autoreszingMask 适配俩个必须去掉一个不能共存

186> 响应者链条 —> 监听触摸事件的做法 iOS 3.2之后 苹果推出手势识别器 (Gesture Recognizer)能够监听任何view的点击事件 但是UIImageView 默认不能和用户交互 所以我们要设置属性!一个view可以添加多个手势识别器但是只有一个手势识别能有用 所以我们要添加多个并且同时执行那么 都要设置代理 其次调用代理的同步方法 返回的都是BOLL值

187> md5解密网站 用户的隐私数据只有在用户输入的那一刻是明文 其余的情况都是暗文!MD5加密目前已经不是绝对安全 可以根据32位的字符推敲出来
  • 第一种方式:加盐(Salt) 在明文的固定位置插入随机字符串然后再进行MD5加密! 
  • 第二种方式: 先对明文进行MD5加密 然后再乱序\再添加固定的东西(加密肯定有不少种方式去实现)
  • http://www.cmd5.com/

188> 一个请求默认的就是GET请求 所以我们不需要设置我们的请求 服务器返回的数据url 应该直接返回后面的 因为我们的域名是不停的在变的 所以我们应该自己拼串!

189> KVC方法使用前提:字典中所有的key必须都能在模型属性中找到 如果没有会直接崩溃 NSXMLParser XML解析

190> 视频播放类使用
  • MPMoviePlayerViewController // 只能全频播放  
  • MPMoviePlayerController  // 可以随意控制播放的尺寸
  • MPMoviePlayerViewController 这个类很简单之所以能播放完全是因为有  MPMoviePlayerController
  • // mp4
  • // rmvb
  • // avi
  • // 软件解码器
  • /**
  •  解码
  •  1> 硬件解码 : 支持MP4
  •  2> 软件解码 : 解码器, VLC\ffmpeg
  •  */

191> 视频的基本使用
  • /**
  •  *  控制当前控制器支持哪些方向
  •  *  返回值是UIInterfaceOrientationMask*
  •  */
  • - (NSUInteger)supportedInterfaceOrientations
  • {
  •     /**
  •      *  UIInterfaceOrientationMaskPortrait :竖屏(正常)
  •      *  UIInterfaceOrientationMaskPortraitUpsideDown :竖屏(上下颠倒)
  •      *  UIInterfaceOrientationMaskLandscapeLeft :横屏向左
  •      *  UIInterfaceOrientationMaskLandscapeRight :横屏向右
  •      *  UIInterfaceOrientationMaskLandscape :横屏(横屏向左\横屏向右)
  •      *  UIInterfaceOrientationMaskAll :全部方向(包括上面的所有情况)
  •      */
  •     return UIInterfaceOrientationMaskPortrait;
  • }

  •     // 移除程序进入后台的通知\即进入后台不要自动销毁我们要保留我们当前的播放进度
  •  [[NSNotificationCenter defaultCenter] removeObserver:selfname:UIApplicationDidEnterBackgroundNotificationobject:nil];

192> 要看当前的控制器属于那一个控制器然后重写然后再覆盖方法

193>  HTTP协议
  • /*
  • 1. 面试题:聊一下HTTP协议(协议的完整通信过程)
  • 2.通信过程
  • 1> 请求
  • * 客户端— > 服务器
  • * 请求的内容
  • a. 请求行(请求方法\HTTP协议\请求资源路径)
  • b. 请求头(描述客户端的信息)
  • c. 请求体(POST请求才需要有,存放具体数据)

  • 2> 响应
  • * 服务器—> 客户端
  • * 响应的内容
  • a. 状态行(响应行\状态码)
  • b. 响应头(服务器信息\返回数据的类型\返回数据的长度)
  • c. 实体内容(响应体\返回给客户端的具体内容)

  • 3> HTTP请求的方法
  • 1> GET
  • * 参数都拼接在URL后面
  • * 参数有限制

  • 2> POST
  • * 参数都在请求体
  • * 参数没有限制(根据服务器的承受压力)

  • 4> iOS中发送GET\POST请求的手段
  • 1> NSURLConnection
  • * 发送一个同步请求
  • + (nullable NSData *)sendSynchronousRequest:(NSURLRequest*)request returningResponse:(NSURLResponse* __nullable * __nullable)response error:(NSError**)error
  •  */

194> 一个 是局部变量为什么创建完了没有被销毁呢?那么和我们的UIAlartView很像 他创建完了也是局部变量 但是一直都在 他默认会有一个窗口引用着所以窗口在我们UIAlartView 就在!

195> KVC:会将字典中所有的键值队赋值给模型中对应的属性 那么如果模型中没有就会崩溃 所以这是KVC的致命缺点

196> 新浪微博Cell结构图

cell的结构图.png

197>  如何将项目导入git中 通过终端(ter)来加入终端

198>  CorePlot 一个非常好的图标框架!做各种东西都非常好用!

199>  集成刷新控件 (自动进入刷新状态不会触发监听方法)
  •  UIRefreshControl*control = [UIRefreshControlalloc] init];
  •  [self.view addSubview:control];

200>  开发中的小技巧你想看那个地方用了你的类  直接改类名看报错 然后修改 然后再修改回去!

201>  -568h@2x 的图片 只支持Default.png 也就是LaunchImage 图片 别的 例如新特性不支持是不会显示到对应的位置!也不能根据Default 里面的 json 来修改一下 没有用! 图片 Unassigned 就是图片没有赋值到时候就不知道到那里用!

202> 什么没有允许打开程序不被同意需要修改 

203>  分页查询的方法,我们想查询10万条数据的里面的 其中10条数据 我们要用SQLite3 数据库的方式SQL 结构化查询语句对关系型数据库中的数据进行定义和操作的语言 CRUD 增删改查
  • 数据库可以分为2大种类:
  •  1.关系型数据库(主流)  : PC端:Oracle、MySQL、SQL Server、Access、DB2、Sybase (不能跑到嵌入式设备) SQLite
  •  2.对象型数据库
  • SQL 语句的特点:不区分大小写,每条语句都必须以分号;结尾 数据库中不可以使用关键字来命名表、字段名字
  • 数据定义语句:DDL 创表、删表
  • 数据操作语句:DML 添加、修改、删除表中的数据
  • 数据查询语句:DQL 查询获得表中的数据
  • SQLite 将数据划分为以下几种存储类型:
  • integer : 整型值  real : 浮点值  text : 文本字符串 blob : 二进制数据 (比如文件) 但是SQLite 是无类型的 但是(主键除外)
  • 数据库中的字符串应该用单引号‘’括住  设计数据库必须有一条主键告诉那么到时候我们就知道什么是唯一的
  • 数据库插入数据可以针对单独的字段的插入数据 其余的为空 但是主键必须有
  • 主键的设计原则:
  • * 主键应当是对用户没有意义的
  • * 永远也不要更新主键
  • * 主键不会包含动态变化的数据
  • * 主键应当由计算机自动生成
  • 给子段起别名 给表起别名 那么我们就可以先给表起别名了 然后我们在查询字段的时候 我们s.age 点出属性
  • 使用count(*) 来计算记录字段的个数 排序 order by score(默认是升序) asc desc 降序
  • 使用limit 可以准确控制查询结果的数量,比如每次只查询10条数据
  • select * from t_student limit 4, 8; // 可以理解:跳过最前面4条语句,然后取8条记录 用来做分页查询
  • SQL : (约束)
  • 0> 简单约束(建表的时候可以给特定的字段设置一些约束条件)  not null (非空) unique(唯一) default (默认字段)
  • 1> 主键约束:(每一张表必须有一个主键,可以联合主键来进行约束id  name 复合主键) 默认包涵约束not null (非空) unique(唯一)  自动增长 integer 类型 autoincrement
  • 2> 外键约束:(我们某一张表的一个字段依赖于另外一张表的主键如果我们手动填写只能算是字段) 建立表1表2之间的联系然后进行约束
  • 多表查询:(表连接查询)
  • 需要联合多张表才能查到想要的数据(联合表的同时需要给表取别名然后添加约束查询)
  • 表连接的类型:
  • 内连接:inner join 或者 join (显示的是左右表都有完整字段值的记录)
  • 左外连接: left outer join (保证左表数据的完整性左边写的表的数据全部必须显示出来不管符不符合条件)
  • 嵌套查询 查的东西 一层一层嵌套查询下去
  • // SQL注入漏洞
  •    
  •     /**
  •      登录功能
  •     
  •      1.用户输入账号和密码
  •      * 账号:123' or 1 = 1 or '' = '
  •      * 密码:456654679
  •     
  •      2.拿到用户输入的账号和密码去数据库查询(查询有没有这个用户名和密码)
  •      select * from t_user where username = '123' and password = '456';

  •      select * from t_user where username = '123' and password = '456';
  •      */
  •    
  •     // 1.定义sql语句
  •     const char *sql = "select id, name, age from t_student where name = ?;";
  •    
  •     // 2.定义一个stmt存放结果集
  •     sqlite3_stmt*stmt = NULL;
  •    
  •     // 3.检测SQL语句的合法性
  •     int result = sqlite3_prepare_v2(_db, sql, -1, &stmt,NULL);
  •     if (result == SQLITE_OK) {
  •         NSLog(@"查询语句是合法的");
  •        
  •         // 设置占位符的内容
  •         sqlite3_bind_text(stmt,1, "jack", -1,NULL);
  •        
  •         // 4.执行SQL语句,从结果集中取出数据
  • //        int stepResult = sqlite3_step(stmt);
  •         while(sqlite3_step(stmt) ==SQLITE_ROW) { // 真的查询到一行数据
  •             // 获得这行对应的数据
  •            
  •             // 获得第0列的id
  •             intsid = sqlite3_column_int(stmt,0);
  •            
  •             // 获得第1列的name
  •             constunsigned char *sname = sqlite3_column_text(stmt,1);
  •            
  •             // 获得第2列的age
  •             intsage = sqlite3_column_int(stmt,2);
  •            
  •             NSLog(@"%d %s %d", sid, sname, sage);
  •         }
  •     } else {
  •         NSLog(@"查询语句非合法");
  •     }

  • // SQL模糊查询 ? %0%
  • + (NSArray *)studentsWithCondition:(NSString *)condition
  • {
  •     // 0.定义数组
  •     NSMutableArray*students = nil;
  •    
  •     // 1.定义sql语句
  •     const char *sql = "select id, name, age from t_student where name like ?;";
  •    
  •     // 2.定义一个stmt存放结果集
  •     sqlite3_stmt*stmt = NULL;
  •    
  •     // 3.检测SQL语句的合法性
  •     int result = sqlite3_prepare_v2(_db, sql, -1, &stmt,NULL);
  •     if (result == SQLITE_OK) {
  •         NSLog(@"查询语句是合法的");
  •         students = [NSMutableArrayarray];
  •        
  •         // 填补占位符的内容
  •         NSString*newCondition = [NSStringstringWithFormat:@"%%%@%%", condition];
  • //        NSLog(@"%@", newCondition);
  •         sqlite3_bind_text(stmt,1, newCondition.UTF8String, -1,NULL);
  •        
  •         // 4.执行SQL语句,从结果集中取出数据
  •         while(sqlite3_step(stmt) ==SQLITE_ROW) { // 真的查询到一行数据
  •             // 获得这行对应的数据
  •            
  •               ZZStudent*student = [[IWStudentalloc] init];
  •            
  •             // 获得第0列的id
  •             student.ID= sqlite3_column_int(stmt,0);
  •            
  •             // 获得第1列的name
  •             constunsigned char *sname = sqlite3_column_text(stmt,1);
  •             student.name= [NSString stringWithUTF8String:(constchar *)sname];
  •            
  •             // 获得第2列的age
  •             student.age= sqlite3_column_int(stmt,2);
  •            
  •             // 添加到数组
  •             [students addObject:student];
  •         }
  •     } else {
  •         NSLog(@"查询语句非合法");
  •     }
  •    
  •     return students;
  • }

204> App动态更新服务平台

205> iPad开发: 2010年苹果公司发布的平板电脑 定位介于苹果的智能手机iPhone和笔记本电脑产品之间 和iPhone一样 搭载的是iOS操作系统 所以可以开发iPad程序
  • iPhone和iPad开发的区别
  • > 屏幕尺寸\分辨率
  • > UI元素的排布\设计 : 尺寸大所以可以容乃更多的UI元素和设计风格
  • > 键盘 : iPad右下角有个特别的按钮可以退出键盘但是iPhone上没有
  • > API : iPad多了一些特有的类 比如: UIPopoverController(点击模块区域用一个带箭头的view显示) UISplitViewController(大控制分俩个控制器切割) 共有API: 如UIActionSheet iPad只悬浮在中间 而iPhone从底部出来
  • > 屏幕方向的支持 iPhone 不支持上下颠倒 iPad都支持 横竖屏的支持 iPhone应用要么竖屏 要么横屏(游戏) iPad应用最好同时支持横屏 竖屏(苹果官方建议) iPhone 程序是iPhone\iPad都支持调试
  • > ……

206> 什么是UIPopverController (iPad开发中常见的一种控制器)iPhone上不允许使用跟其它控制器不一样,它直接继成自NSObject 而不是继成UIViewController 只占用屏幕部分空间来呈现信息,而且显示在屏幕的最前面
  • 使用步骤:
  • 1>设置内容控制器
  • 由于UIPopverController 直接继成NSObject 不具备可视化能力 相当于模型里面没有View 所以上面的内容必须由另外一个继承自UIViewController 的控制器来提供,这个控制器称为”内容控制器”
  • 2>设置内容的尺寸
  • 显示出来占据多少屏幕空间
  • 3>设置显示位置
  • 从哪个地方冒出来
  • 设置内容的尺寸有2种方法
  • p @property (nonatomic)CGSize popoverContentSize;
  • p - (void)setPopoverContentSize:(CGSize)size animated:(BOOL)animated;
  • 以上方法和属性都是UIPopoverController

  • 设置显示的位置有2种方法
  • p 围绕着一个UIBarButtonItem显示(箭头指定那个UIBarButtonItem
  • - (void)presentPopoverFromBarButtonItem:(UIBarButtonItem*)item permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated;
  • item :围绕着哪个UIBarButtonItem显示
  • arrowDirections :箭头的方向
  • animated :是否通过动画显示出来
  • p 围绕着某一块特定区域显示(箭头指定那块特定区域)
  • - (void)presentPopoverFromRect:(CGRect)rect inView:(UIView*)view permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated;
  • rect :指定箭头所指区域的矩形框范围(位置和尺寸)
  • view rect参数是以view的左上角为坐标原点(00
  • arrowDirections :箭头的方向
  • animated :是否通过动画显示出来

Pasted Graphic_2.tiff

  • 如果想让箭头指向某一个UIView的做法有2种做法,比如指向一个button
  • p 方法1
  • [popover presentPopoverFromRect:button.boundsinView:button permittedArrowDirections:UIPopoverArrowDirectionDownanimated:YES];
  • p 方法2
  • [popover presentPopoverFromRect:button.frameinView:button.superviewpermittedArrowDirections:UIPopoverArrowDirectionDownanimated:YES];

  • popover的使用过程中,经常会遇到这个错误
  • -[UIPopoverController dealloc] reached while popover is still visible.
  • p 错误的大体意思是:popover在仍旧可见的时候被销毁了(调用了dealloc
  • p 从错误可以得出的结论
  • popover仍旧可见的时候,不准销毁popover对象
  • 在销毁popover对象之前,一定先让popover消失(不可见)
  • 内容控制器可以自行设置自己在popover中显示的尺寸
  • p iOS 7之前
  • @property (nonatomic,readwrite)CGSize contentSizeForViewInPopover;
  • p iOS 7开始
  • @property (nonatomic)CGSize preferredContentSize;
  • 以上属性都是UIViewController

  • 代理对象
  • @property (nonatomic,assign) id <UIPopoverControllerDelegate> delegate;
  • 是否可见
  • @property (nonatomic,readonly, getter=isPopoverVisible)BOOL popoverVisible;
  • 箭头方向
  • @property (nonatomic,readonly) UIPopoverArrowDirectionpopoverArrowDirection;
  • 关闭popover(让popover消失)
  • - (void)dismissPopoverAnimated:(BOOL)animated;

  • 默认情况下
  • p 只要UIPopoverController显示在屏幕上,UIPopoverController背后的所有控件默认是不能跟用户进行正常交互的
  • p 点击UIPopoverController区域外的控件,UIPopoverController默认会消失
  • p
  • 要想点击UIPopoverController区域外的控件时不让UIPopoverController消失,解决办法是设置passthroughViews属性
  • @property (nonatomic,copy) NSArray *passthroughViews;
  • p 这个属性是设置当UIPopoverController显示出来时,哪些控件可以继续跟用户进行正常交互。这样的话,点击区域外的控件就不会让UIPopoverController消失了
  • UIPopoverController这个类是只能用在iPad中的
  • 要想在iPhone中实现popover效果,必须得自定义view,可以参考
  • p http://code4app.com/ios/Popover-View-in-iPhone/4fa931bd06f6e78d0f000000
  • p http://code4app.com/ios/Popup-Menu/512231ac6803fa9e08000000
  • p
Pasted Graphic 1.tiff

207> iOS中和iPad中modal 的区别
  • iPhone开发中
  • p Modal是一种常见的切换控制器的方式
  • p 默认是从屏幕底部往上弹出,直到完全盖住后面的内容为止
  • iPad开发中
  • p Modal的使用频率也是非常高的
  • p 对比iPhone开发,ModaliPad开发中多了一些用法
  • 什么叫呈现样式
  • p Modal出来的控制器,最终显示出来的样子
  • p
  • Modal常见有4种呈现样式
  • p UIModalPresentationFullScreen 全屏显示(默认)
  • p UIModalPresentationPageSheet
  • 宽度:竖屏时的宽度(768
  • 高度:当前屏幕的高度(填充整个高度)
  • p UIModalPresentationFormSheet :占据屏幕中间的一小块
  • p UIModalPresentationCurrentContext :跟随父控制器的呈现样式
  • 什么叫过渡样式
  • p Modal出来的控制器,是以怎样的动画呈现出来
  • p
  • Modal一共4种过渡样式
  • p UIModalTransitionStyleCoverVertical :从底部往上钻(默认)
  • p UIModalTransitionStyleFlipHorizontal :三维翻转
  • p UIModalTransitionStyleCrossDissolve :淡入淡出
  • p UIModalTransitionStylePartialCurl :翻页(只显示部分,使用前提:呈现样式必须是UIModalPresentationFullScreen

208> 响应者 UIImageView不能点击那么实现view的touches方法就能监听点击

209> 图形处理用到C语言底层的东西去获得图片的像素然后改像素那么选择放弃吧 MJ哥说的!

210> 遵守协议的另外一种做法: ZZCustomView<XXXDelegate> * view = [ZZCustomView alloc] init];

211> 设置frame新方式 self.frame = [UIScreen mainScreen].applicationFrame;

212> 目里面的文件夹有在硬盘上面是有的 但是项目中只要是黄色的文件夹 装在手机上都属于同一目录下所以在加载一些html 的时候 css 文件路径要在html中去改 那我们在拖东西的文件到项目中的时候 就要勾选下面的选项那么会创建蓝色的文件夹 我们项目中是什么文件夹 沙盒里面就是什么文件夹!

213> 写的一些方法 或者效果在即将显示的时候就做了一些事 但是一闪而过 那么思考的方向是 覆盖父类的方法 这个控制器即将显示 或者显示完毕的时候做了一些处理那么我们不让他执行不让他做就好!

214> 资源访问 拖一些东西到项目中 勾选项的问题 最终的效果是沙盒里面有 才算有效 那么可能真的会去沙盒看 Build Phases  —> Copy Bundle Resources 看看有没有 要看沙盒的文件路径 他是怎么显示我们就怎么访问!有时候我们要压缩一下 .bundle 这样就是一个压缩文件也要注意访问的路径.

215> 文本输入框检查纠正
屏幕快照 2016-05-20 下午5.20.06.png
  • 文本框输入clearButtonAlways 就是输入之后都有 而editing 这种则只会是在输入或者再次输入才会有!

216> 用xib\storyBoard 时切换编辑样式
  屏幕快照 2016-05-20 下午5.33.51.png

217> 我们在做登录不用第三方框架 那么点击了之后 整个控制器view 不能跟用户交互 而返回结果后才能跟用户交互

218> 牵扯到几次都要实现的动画 用图层动画 CAKeyframeAnimation 帧动画图层动画

屏幕快照 2016-05-20 下午6.06.12.png
  • 那么我们显然要添加图层动画

219> 响应者 事件传递 监听者这些必须要好好过度 一个控件不能处理事件 那么抛给它的父控件去处理 父控件处理不了 就抛给控制器去处理!

220> iPad中当一个宽度高度随着父控件宽度高度改变 时刻改变 例如旋转一定要添加的属性

屏幕快照 2016-05-20 下午6.33.39.png

221> iPad 开发宽度高度随着屏幕旋转改变而改变
屏幕快照 2016-05-20 下午6.53.51.png

222> 在上面那个方法中 iPad 开发中是指即将旋转那么在即将旋转的过程的宽度高度还是原来的 而在iPad开发中默认进入程序就是竖屏 所以我们要在分层的时候 用好autoresizingMask 就是那6根线用好这些属性!

223> 在iPhone\iPad开发,控制器的view的autoresizingMask 默认是伸缩宽度和高度的 所有要跟随屏幕的改变而改变的时候我们需要手动清掉这个属性

224> 转场动画: 这个动画我们都不需要写[self.view addSubView:] 这个方法 他会将后面添加的view 覆盖到原来的view上面然后添加进去!
屏幕快照 2016-05-23 下午5.44.39.png

225> 转场动画的另外一种方式: 这种动画就有很多种方式那么复习核心动画
屏幕快照 2016-05-23 下午6.03.44.png

226> 探索系统的控件我们要改成我们想要的样式例如设置图片设置文字设置重新的东西我们要有一定的探索精神我们就一层一层的去扒看里面到底是牛是马
屏幕快照 2016-05-23 下午6.38.00.png


227>  要想在switch 语句中声明他是变量必须要用大括号括住:
屏幕快照 2016-05-24 上午10.29.44.png

228> translation 弹簧效果
屏幕快照 2016-05-24 上午10.45.08.png

229>  通过storyboard \ xib 创建的控制器如何退出到登录界面
屏幕快照 2016-05-24 上午10.50.38.png

230> 在MVC中view才是最关键最重要的 view我们想怎么写就怎么写 写出来是什么样子就是什么样子 controller 只是我们的容器来包装我们这个view以及显示出来 所以view 加到某个控制上 [self.view addSubview:menuVc.view];

231> 大众点评是开发自己的api的要做团购应用的可以去写这个!

232> 静态库编译上的报错 i386 4S  x86_64 6 的架构 项目编译语言的问题!
屏幕快照 2016-05-24 下午3.36.14.png

233>  URL定义 应用之间的跳转
屏幕快照 2016-05-24 下午4.54.17.png

234>  另外一个应用会判别你是从那个按钮分享跳转按钮过来的 快速将一个url转换成字符串
屏幕快照 2016-05-24 下午5.11.05.png

235>   storyboard 直接嵌套导航控制器
屏幕快照 2016-05-24 下午5.15.00.png

236> 应用间的跳转到相应界面然后跳转回去 例如分享登录
屏幕快照 2016-05-24 下午6.20.25.png

屏幕快照 2016-05-24 下午6.19.41.png

237> SSO授权 直接跳转页面点击某个帐号密码直接登录
屏幕快照 2016-05-25 上午10.30.56.png

238>  社交分享:
屏幕快照 2016-05-25 上午10.41.31.png

239>  如何实现社交分享:
屏幕快照 2016-05-25 上午10.44.14.png

240> 快速切换应用的中英文:
屏幕快照 2016-05-25 上午10.54.22.png

241>  系统自带的分享首先在设置界面看到可以分享的平台要求注册过这个帐号:
屏幕快照 2016-05-25 上午11.01.11.png

242> 通讯录访问首先框架是纯C语言:

屏幕快照 2016-05-25 下午6.03.05.png


243>  在访问允许隐私的问题的时候苹果的做法都必须弹框那么这个不想我们的蓝牙或者定位需要我们手动调用一次方法
屏幕快照 2016-05-25 下午6.04.48.png


244>  方法实例!既然是纯C语言的所以我们需要手动释放
屏幕快照 2016-05-25 下午6.15.07.png


245>  通讯录访问方法
屏幕快照 2016-05-25 下午6.27.04.png


246> 但是关于电话号码这个可能是家庭号码可能是公司电话号码所以要特俗处理看打印
屏幕快照 2016-05-25 下午6.26.11.png

247>  桥接(O —> OC / OC —> C) +

猜你喜欢

转载自blog.csdn.net/zz_iosdeveloper/article/details/53944474