iOS 开发小记(十二)
一、RAC
[[[NSUserDefaults standardUserDefaults] rac_channelTerminalForKey:@"token"] subscribeNext:^(id x) { [_sharedJsonClient.requestSerializer setValue:[_sharedJsonClient getAuth] forHTTPHeaderField:@"Authorization"]; }];
可以用RAC对NSUserDefaults进行监听,保持数据同步
二、设计模式
[AFHttpAPIClient baseRequestWithHttpClient:[AFHttpAPIClient sharedJsonPostClient] Method:@"POST"
path:API_hot_subject_list parameters:@{@"len":@(20)} toastInView:nil modelClass:[CommonModel class]
complete:^(NSURLSessionDataTask *task);
如果需要对json和xml等,用不同的client,可以采用这种设计模式。
是不是叫做工厂模式?
同时,
封装的时候带上error属性, [modelClass objectWithKeyValues:responseObject error:&err];
三、UIKit
//The problem is, the backBarButtonItem property itself is nil! So, passing any message to it will have no effect [[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], [MyNavigationController class], nil] setTitleTextAttributes:titleAttributes forState:UIControlStateNormal]; [item setTitleTextAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14], NSForegroundColorAttributeName:[UIColor whiteColor]} forState:UIControlStateNormal]; self.navigationItem.backBarButtonItem = item; //下面的代码是无效的! // [item setTitleTextAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14], NSForegroundColorAttributeName:[UIColor blackColor]} forState:UIControlStateNormal];
四、编译
首先明确一点,Header Search Paths 顾名思义就是用来存放 Project 中头文件的搜索根源,没有被add到项目里的头文件,可以通过配置Header Search Paths 来引入头文件,这样的好处可以不让project 包含的文件太多,便于管理。
浅显一点的区别是,编码时候通过 #include 引入头文件的方式有两种 <> 和 ""。<> 是只从 Header Search Paths 中搜索, 而 "" 则能从 Header Search Paths 和 User Header Search Paths 中搜索。换言之 ,假如你把 路径加到 User Header Search Paths 中,那么 你用 #include <file.h> 的方式去引入对应的头文件,就会报错。 如果加到 Header Search Paths, 就没有问题了。
具体一点的区别是,<> 是从系统目录空间 (对应 Header Search Paths)中搜索文件, "" 是从用户目录空间(对应 User Header Search Paths)中搜索文件。如果你把路径加到 User Header Search Paths 中,而 <> 无法从系统目录空间中找到新加的路径,从而报错。
参考
五、UIKit
隐藏StatusBar 注意事项
不自动锁屏
TextField的键盘完成按钮
// This should be called whenever the return values for the view controller's status bar attributes have changed. If it is called from within an animation block, the changes will be animated along with the rest of the animation block. - (void)setNeedsStatusBarAppearanceUpdate NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; - (void)hideStatusBar { if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) { [self prefersStatusBarHidden]; [self performSelector:@selector(setNeedsStatusBarAppearanceUpdate)]; } } //不自动锁屏 [UIApplication sharedApplication].idleTimerDisabled=YES; //注意不要轻易使用,并且记得重新设置回NO //为TextField添加inputAccessoryView,键盘添加完成按钮 UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(SCREEN_WIDTH-55, 5, 50.0f, 30.0f)]; button.layer.cornerRadius = 4; [button setBackgroundColor:RGB16(COLOR_FONT_RED)]; button.titleLabel.font = [UIFont systemFontOfSize: 15.0]; [button setTitle:@"完成" forState:UIControlStateNormal]; [button addTarget:self action:@selector(completeInput) forControlEvents:UIControlEventTouchUpInside]; UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 40.0f)]; [toolbar addSubview:button]; toolbar.backgroundColor = RGB16(COLOR_BG_LIGHTGRAY); self.messageTextField.inputAccessoryView = toolbar;
抽屉式动画 NMultiVideoViewController
NMultiVideoViewController* multiVideoViewController=[[[NMultiVideoViewController alloc] init]autorelease]; MSDynamicsDrawerViewController* drawerController=[[MSDynamicsDrawerViewController alloc] init]; [drawerController setRevealWidth:120 forDirection:MSDynamicsDrawerDirectionRight]; MultiRoomConfigViewController* roomConfigController=[[[MultiRoomConfigViewController alloc] initWithStyle:UITableViewStyleGrouped] autorelease]; RoomMemberViewController* roomMenberController=[[[RoomMemberViewController alloc] initWithStyle:UITableViewStyleGrouped]autorelease ]; roomMenberController.model=model; multiVideoViewController.model=model; multiVideoViewController.roomMemberController = roomMenberController; multiVideoViewController.roomConfigController = roomConfigController; //设置成员列表控制器、设置操作列表控制器、设置显示控制器 [drawerController setDrawerViewController:roomConfigController forDirection:MSDynamicsDrawerDirectionRight]; [drawerController setDrawerViewController:roomMenberController forDirection:MSDynamicsDrawerDirectionLeft]; [drawerController setPaneViewController:multiVideoViewController]; [self presentViewController:drawerController animated:YES completion:^{ }];
六、异常
OC的异常
@try { [_imageView initOpenGL]; } @catch (NSException *exception) { } @finally { }
NSSetUncaughtExceptionHandler 设置最高等级的错误处理
七、视频
若以目前主流的HD影片来推估,并以下列条件进行试算:
- 解析度=1920 x 1080
- 颜色取样深度=24bit(R、G、B各色8bit)
- 每秒帧数=60帧
那么每秒需要的流量可能是多少?
1920 x 1080 x 24bit x 60=2985984000bit
1920 x 1080 x 24bit x 60=2985984000bit
2985984000bit/8bit/1024/1024=355.957MB
以2小时的电影来说,就需要占用2.44TB的储存
H264
在系统层面上,H.264提出了一个新的概念,在视频编码层(Video Coding Layer,VCL)和网络提取层(Network Abstraction Layer,NAL)之间进行概念性分割,前者是视频内容的核心压缩内容之表述,后者是通过特定类型网络进行递送的表述,这样的结构便于信息的封装和对信息进行更好的优先级控制。
视频压缩编码技术可以分为两大类:无损压缩和有损压缩。
八、其他
1、保存文件为HTML格式,然后用UIWebView加载。
2、UIWindow是不会旋转的,旋转的是window上的view,所以view的frame永远是window的bounds,不会变 。
3、NSTimer 我们通常会用在背景计算,更新一些数值资料,而如果牵涉到画面的更新,动画过程的演变,我们通常会用CADisplayLink。
[_displayLink invalidate];
[_displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
invalidate 已经包括了上面的remove
CADisplayLink是一个能让我们以和屏幕刷新率同步的频率将特定的内容画到屏幕上的定时器类。
从原理上不难看出, CADisplayLink 使用场合相对专一, 适合做界面的不停重绘,比如视频播放的时候需要不停地获取下一帧用于界面渲染。
NSTimer的使用范围要广泛的多,各种需要单次或者循环定时处理的任务都可以使用。