每日小记——ios系列

2016年6月13日
这两天开始着手自己的APP(ios客户端的开发),碰到了很多问题,不过都一一解决了。
1.在子类化的cell里面需要添加一个按钮,当点击这个按钮时需要实现页面的跳转。
解决方法:
在cell的.h文件中声明该Button,在该cell所在的TabelView中给该Button绑定方法,——————cell.button addtaget:self....@selector(push).......—————
这样就可以在该TabelView所在的控制器实现push方法然后实现页面跳转。

2.由于cell的重用,在子类化的cell中当数据源数组中有几组数据,该cell的初始化方法以及自己定义的方法就会执行多少次,所以在cell中定义的各种对象都会被重复初始化很多次,当要在cell中实例化一个模型或者字典时,建议通过tableview在初始化cell的时候传入cell.dictornay.....

2016年6月14日
在实现收货地址的时候有自己写java接口的冲动,然后还是自己通过本地数据库的方式实现了,这样就狠狠的恶补了一下数据库知识。我使用的是sqlit3,采用的是fmdb这个第三方,因为收货地址有增删改查功能,在涉及到删和改的时候就要保证我选择的数据唯一,所以我设置了一个自增主键,并在想对应的收货地址的模型里面设置了一个u_id属性(主键唯一),通过这个u_id来确定该信息唯一。

今天碰到的一个同学也是从事iOS开发的,不过我觉得他是那种侥幸者,基本符合大家口中说的培训出来的,能力也确实不行。我实习也一年多的时间了,勉勉强强能够独立开发,毕竟有计算机专业的基础,比那些完全从oc开始跨入计算机行业的朋友学习肯定要快的多,在我看来不论是工作还是自己学习,都要讲求效率,看些比较底层的原理还是有必要的,其实不难,静下心来总是能够看的懂的,虽然一直有工作,不过不是如人意,不过之前刚拒绝了一个8K的offer,在现在iOS还是比较难找工作的情况下,我居然那么奢侈的拒绝了offer,我自己也是醉,不过为了技术,我还是选择了大神比较多的公司,虽然薪资低一点,但对于我这种技术痞子来说还是觉得能力比较重要,目标三年半个全栈!

2016年6月15日
今天早上5点就自己醒了,然后就看了点runloop的知识,这里简单记一下自己所学到的东西而已。
在创建一个定时器时,需要将该定时器加入到一个runloop中,并给该定时器指定一个runloopModel(运行模式),一个定时器只能在一个model下跑圈,一个mode下可以有多个定时器。定时器在实现是其实应该是先将某一个定时器加入到某一种模式,runloop随之启动该mode然后timer随之启动。模式选择很重要,程序在运行过程中的模式在随时切换,比如滑动模式和默认模式,添加在默认模式下的定时器是不会在滑动模式下运行的。如果要在两种模式下都运行,可以使用comMonModes占位(comMonModes标记了上面两种模式)

前两天一直忙着毕业的事就没怎么写简书,今天搬完家之后就静下心来理解了下block块作为参数的是什么样的原理和怎么样实现的。既然作为参数就和别的类型的参数一样,在调用携带block参数的函数时,需要传递时向该方法传递一个block块

1.先在BackViewController中声明该携带block参数的方法,并实现

记得在.h文件中声明
-(void)mytestWithBlock:(PassingValueBlock)passingValue{
     passingValue(@"It is a block");
}

因为这里使用到了block,所以需要先对block先在.h进行声明.

BackViewController*backView=[[BackViewController alloc]init];
    [backView mytestWithBlock:^(NSString *str){
        NSLog(@"%@",str);    
    }];

实现步骤:
携带block的方法被调用,携带block参数的方法中调用了这个block,此时block块被使用进入block实现内部。

++++++++++++++++++++
看到群里有人问
popToViewController的用法 就写了下了 希望能帮到有需要的人

[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:2] 
animated:YES];

for (UIViewController *temp in self.navigationController.viewControllers) {  
    if ([temp isKindOfClass:[你要跳转到的Controller class]])
 {   
 [self.navigationController popToViewController:temp animated:YES];   
        }     
  }

++++++++++++++++++++

昨天在处理证书(打调试证书)的时候发现,一个99美刀的账号的iOS development是有一定数量限制的,好像是三个。
真机调试需要:开发者凭证.p12(通过iOS development生成的cer然后导出.p12证书)+(mobileprovition文件)描述文件

++++++++++++++++++++
在kvc 或者kvo中有(setValue forKey或着forKeyPath 两个方法去)
首先他们都是用于获取某一个实例话对象中某一属性的值。
keyPath用起来比较强大,比如(model(实例的对象)里面有个model1,model1里面有个model2)如果要修改model2里面的一个name属性的话,就可以写成[model set @"name" forkeyPath model.model1.model2.name];(注意:model model1 model2都应该被实例化)
+++++++++++++++++++++
关于多线程
有全局并发队列,所以可以获取
没有全局串行队列,队列需要自己创建

同步函数和异步函数
同步函数不会创建线程,异步函数会创建线程
同步函数要求立马执行,异步线程在执行完当前执行操作后下一次再进入的时候执行

主队列是比较特殊的串行队列 主队列中的任务都会在主线程中执行

++++++++++++++++++
loadview 和viewDidLoad方法

在控制器的view为nil的情况下会调用loadview方法,在内存警告的情况下, 如果它的 view 不在当前正在使用的 view hierarchy 里面,且你的控制器实现了 loadView 方法,那么这个 view 将被 release, loadView 方法将被再次调用来创建一个新的 view。

+++++++++++++++++++++++++++

UITextView自定选择文字后的菜单
 在ViewDidLoad中加入:
UIMenuItem *menuItem = [[UIMenuItem alloc]initWithTitle:@"分享到新浪微博" action:@selector(changeColor:)];    
 UIMenuController *menu = [UIMenuController sharedMenuController];    
 [menu setMenuItems:[NSArray arrayWithObject:menuItem]];    
 [menuItem release];    


+++++++++++++++++++++++++++++++++++++++++

计算当前文件大小。断点下载的时候获取已下载文件大小
-(NSInteger)getFileSize:(NSString*)path{
 NSFileManager*manager = [NSFileManager defaultManager]; NSDictionary*dict = [manager attributesOfItemAtPath:path error:nil]; 
return [dict[NSFileSize] integerValue];
}

+++++++++++++++++++++++++
UIWebView 学习
今天空的时候看了点小马哥的视频,学到的还是很多的
我竟然看到的用网页直接播放本地的视频还有PPT,瞬间感觉H5的强大之处啊


控制网页滚动(有时候状态栏被遮住就可以这样处理)


网页自适应显示


自动布局masonry 的高度或者宽度定义变量

    [rightTableBGView mas_updateConstraints:^(MASConstraintMaker *make) {
        
        make.height.equalTo(@(oneheight));

    }];

在使用AFNetWorking时默认解析类型为json,可以通过以下设置切换

发送二进制数据,返回 XML
 AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
1> SAX 解析
mgr.responseSerializer = [AFXMLParserResponseSerializer serializer];

2> DOM 解析(对节点增加或者删除) 二进制数据格式
mgr.responseSerializer = [AFHTTPResponseSerializer serializer];

iOS 响应链:

1.点击一个UIView或产生一个触摸事件A,这个触摸事件A会被添加到由UIApplication管理的事件队列中(即,首先接收到事件的是UIApplication)。
2.UIApplication会从事件对列中取出最前面的事件(此处假设为触摸事件A),把事件A传递给应用程序的主窗口(keyWindow)。
3.窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件。如果想让某个view不能接收事件(或者说,事件传递到某个view那里就断了),那么可以通过刚才提到的三种方式。比如,设置其userInteractionEnabled = NO;那么传递下来的事件就会由该view的父控件处理。
例如,不想让蓝色的view接收事件,那么可以设置蓝色的view的userInteractionEnabled = NO;那么点击黄色的view或者蓝色的view所产生的事件,橙色的view就会成为最合适的view。事件都会由橙色的veiw处理。
所以,不管视图能不能处理事件,只要点击了视图就都会产生事件,关键看该事件是由谁来处理!也就是说,如果视图不能处理事件,点击视图,还是会产生一个触摸事件,只是该事件不会由被点击的视图处理而已!
注意:如果设置父控件的透明度或者hidden,会直接影响到子控件的透明度和hidden。如果父控件的透明度为0或者hidden = YES,那么子控件也是不可见的!

父——————————》子 的过程

在异步线程中发送通知,这个通知调用的方法在异步线程中执行,不在主线程中

视图层次

交换视图位置:
[button1 exchangeSubviewAtIndex:0 withSubviewAtIndex:1];
1.遍历视图

for
(UILabel * l in button1.subviews) {

l.text=[NSString stringWithFormat:@
"%d"
,i++];
}

2.插入视图

[button1 insertSubview:label3 atIndex:1];

将视图label3插入到视图button1的第二位;

[button1 insertSubview:label2 aboveSubview:label1];

将视图label2插到label1上;

[button1 insertSubview:label1 belowSubview:label3];

3.将视图从父类视图中移出;
[label2 removeFromSuperview];
4.[button1 delete :label2];
5.将视图放到最上层 ;
[button1 bringSubviewToFront:label1];
注:写代码时把子视图写到一块,父视图写到一块
6.把视图放到最上下层
[button1 sendSubviewToBack:label1];
7.判断某个视图是某个视图的子视图 返回类型是
bool
类型;
[label1 isDescendantOfView:button1];
7.tag 视图的标志; 可以标志视图。是set 和get函数,设置和取得可以用“.”操作
button1.tag=1;
8.label1.superview 表示label1的父视图;

  1. 隐藏视图 :label1.hidden=YES; 默认为no。
    应用:可以让视图重叠换灯片放映,或动画;如果父视图隐藏,子视图也随之消失

10.视图可能会超出父视图的范围;这时可以更改父视图边界属性裁减出边界 的子视图
button1.clipsToBounds=YES;
UIImageView
1.初始化:
UIImageView *imageview=[[UIImageView alloc] initWithImage:[UIImage imageNamed:@
"2.jpg"
]];
imageview.frame=CGRectMake(20, 20, 140, 220);
imageview.contentMode=UIViewContentModeScaleAspectFit;
让添加的图片按比例填充;
3.imageview和label都不能触发事件 但是可以给他们添加事件
//点击事件 搞清楚是单击还是双击 来处理事件
//声明点击手势 初始化点击手势识别器
当单击判断失败 在触发单击;先判断,不知道是单击还是双击
UITapGestureRecognizer *tgr=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onclick)];
//来添加事件
tgr.numberOfTapsRequired=1;
//区分单击还是双击
tgr.numberOfTapsRequired=2;
[tag addTarget:self action :@selecter(press:)];
//事件
//创建敲击事件的接收器;
[imageview addGestureRecognizer:tgr];
//这个视图来响应,把手势加到视图上面4.imageview.UserInteractionEnabled=YES;
//是否能和用户交互;

5.三中图片填充方式

imageview.contentMode=UIViewContentModeScaleAspectFit;
imageview.contentMode=UIViewContentModeScaleAspectFill;
//按比例添满会超出边界。所以如果超出可以裁减
imageview.clipsToBounds=YES;
imageview.contentMode=UIViewContentModeScaleToFill;

//添满

6.创建视图还可以在appDelegate.m中的application中声明实现

  1. (停靠模式)子视图按某中形式随父视图扩大或缩小;不同的扩大缩小方式特点可以或

labelsub.autoresizingMask=UIViewAutoresizingFlexibleWidth;
labelsub.autoresizingMask=UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
控制视图按比例的开关;
labelsub.autoresizesSubviews=NO;

TabelView 中的滑动到指定的Section
看图:


通过ScrollerView 偏移量确定某一行或者某一个section,通过 NSIndexPath *scrollIndexPath=[_specialTabelView indexPathForRowAtPoint:nowPoint];确定是某一个section 的某一个row


实现UILabel 字体垂直方向顶到头部。黑科技业是最简单的
判断行数然后行数不够在字符串后面加@"\n ".
上传图片时将图片转化为NSData,这样一般可以将图片压缩到100K

+(NSData *)imageData:(UIImage *)myimage
{
NSData *data=UIImageJPEGRepresentation(myimage, 1.0);
if (data.length>100*1024) {
if (data.length>1024*1024) {//1M以及以上
data=UIImageJPEGRepresentation(myimage, 0.1);
}else if (data.length>512*1024) {//0.5M-1M
data=UIImageJPEGRepresentation(myimage, 0.5);
}else if (data.length>200*1024) {//0.25M-0.5M
data=UIImageJPEGRepresentation(myimage, 0.9);
}
}
return data;
}

——————————————
app上架过程中关于IDFA广告标识符
有些第三方SDK中携带了IDFA,上架时如实回答,勾选用途。
http://www.tuicool.com/articles/YJzIjqY
————————————————

ios拨打电话
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"telprompt:126137"]];

————————————————————
关于AVPlayerViewController

AVPlayerViewController实现在网页中播放视频和全屏播放
碰到的难点:
1.视频位置
通过js和oc交互,html传入视频坐标,在原来webView上覆盖一个一样大小的播放器view,点击视频调用本地方法,通过AVPlayerViewController实现播放。
2.监听AVPlayer的播放状态
我是通过KVO实时AVplayer中的rate属性,(float类型)1.0为播放还有-1.0和0两种状态为停止

 if (_playerViewController.player.rate > 0&& _playerViewController.player.error == nil) {
            //playing
                  }
        } else {
             //failed
        }

实现的
3.其他
差不多都是一些计算的问题,偏移量什么的
主要还是之前没用过,在播放状态上卡了很久,才找到一个float类型的rate,瞬间三观。。

app进入后台的通知(可在这里做键盘隐藏操作,或者跳转到指定控制器)

  [[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(applicationWillResignActive) name :UIApplicationWillResignActiveNotification        object:nil];

或者其他一些耗时操作(播放网页音乐等)

[[NSNotificationCenter defaultCenter]  addObserver:self selector:@selector(playYinPin) name:UIApplicationDidEnterBackgroundNotification object:nil];

- (void)playYinPin{
 myTimer = [NSTimer timerWithTimeInterval:1.0f target:self selector:@selector(videoPlay) userInfo:nil repeats:NO];
 
设置中做如下操作

[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSDefaultRunLoopMode];
}

————————获取当前控制器————————
UIViewController *controller = [(UINavigationController *)[(UITabBarController *)[[UIApplication sharedApplication] keyWindow].rootViewController selectedViewController] visibleViewController];
在cell中剪裁图片操作。记得release,否则内存飙升

//裁剪图片
+ (UIImage *)cutImage:(UIImage*)image withSuperView:(UIImageView *)superImageView
{
    //压缩图片
    CGSize newSize;
    CGImageRef imageRef = nil;
    
    if ((image.size.width / image.size.height) < (superImageView.frame.size.width / superImageView.frame.size.height)) {
        newSize.width = image.size.width;
        newSize.height = image.size.width * superImageView.frame.size.height / superImageView.frame.size.width;
        
        imageRef = CGImageCreateWithImageInRect([image CGImage], CGRectMake(0, fabs(image.size.height - newSize.height) / 2, newSize.width, newSize.height));
        
    } else {
        newSize.height = image.size.height;
        newSize.width = image.size.height * superImageView.frame.size.width / superImageView.frame.size.height;
        
        imageRef = CGImageCreateWithImageInRect([image CGImage], CGRectMake(fabs(image.size.width - newSize.width) / 2, 0, newSize.width, newSize.height));
        
    }
    
    UIImage *lastImage = [UIImage imageWithCGImage:imageRef];
    
    CGImageRelease(imageRef);
    
    return lastImage;
//    return [UIImage imageWithCGImage:imageRef];
}

关于单例:
使用单例注意:

1、时间和空间

懒汉式是典型的时间换空间,也就是每次获取实例都会进行判断,看是否需要创建实例,浪费判断的时间。当然,如果一直没有人使用的话,那就不会创建实例,则节约内存空间。

饿汉式是典型的空间换时间,当类装载的时候就会创建类实例,不管你用不用,先创建出来,然后每次调用的时候,就不需要再判断了,节省了运行时间。

2、线程安全

从线程安全性上讲,不加同步的懒汉式是线程不安全的

饿汉式是线程安全的,因为虚拟机保证只会装载一次,在装载类的时候是不会发生并发的。

单例首先作为一个全局状态存在,增加了代码的耦合性,单元测试天敌,可以被使用在任何地方,因此在在某一个地方使用可能对另外一个地方使用造成影响(比如在两个线程中没有指定的优先级)。

单例可能并非唯一存在,保存用户信息如果使用单例,在某一天用户注销登陆状态,那么要清楚用户数据,只能在用户注销时移除单例重新创建了。

关于SDAutoLayout学习记录:

    
    // >>>>>>>>>>>>>>>>>>>>> * cell自适应步骤1 * >>>>>>>>>>>>>>>>>>>>>>>>
    
lineView为cell最下端的控件,bottomMargin为该控件和cell下端的边距
  [self setupAutoHeightWithBottomView:lineView bottomMargin:0];

 // 当你不确定哪个view在自动布局之后会排布在cell最下方的时候可以调用
次方法将所有可能在最下方的view都传过去
//    [self setupAutoHeightWithBottomViewsArray:@[_titleLabel, _imageView] 
bottomMargin:10];

    //重新更新imageView坐标,因为上面获取单元格高度后才能准确让它y方向剧中。
   imageView.sd_resetLayout.centerYEqualToView
(self.contentView).leftSpaceToView(self.contentView,10).widthIs(40).heightIs(40);
    
使用JSContext实现js与oc交互  参考地址:http://blog.csdn.net/kaka_2928/article/details/51463571
// 调节webView字体的大小、OC调js(客户端传值给网页)
 _fontSize = fontSize;
 [weakSelf.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"fontSize(%ld)",(long)fontSize]];

#pragma mark -- webView- 网页加载完成调用此方法
- (void)webViewDidFinishLoad:(UIWebView *)webView {
    
    [self.view hideCustomIndicator];
    //首先创建JSContext 对象(此处通过当前webView的键获取到jscontext)
    JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    // 关联打印异常
    context.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
        context.exception = exceptionValue;
        NSLog(@"exceptionValue-----异常信息:%@", exceptionValue);
    };
    
    // 视频播放(监听网页点击事件,oc调js)
    context[@"nativePlayVideo"] = ^() {
        NSArray *args = [JSContext currentArguments];
        NSString *PlayVideoString = [NSString stringWithFormat:@"%@",args[0]];
        NSLog(@"视频播放nativePlayVideo----PlayVideoString-----%@",PlayVideoString);
        [self playWebVideoTap:PlayVideoString]; 
    };
        
    // 图片查看--跳转到图片查看界面
    context[@"nativePreviewImage"] = ^(){
        NSArray *args = [JSContext currentArguments];
        NSLog(@"args------%@",args);
        NSLog(@"args[0]-------------%@",args[0]);
        NSString *string = [NSString stringWithFormat:@"%@",args[0]];
        NSArray *array = [string componentsSeparatedByString:@","]; //从字符A中分隔成2个元素的数组
        [_imageUrlArray removeAllObjects];
        for (int i = 0; i < array.count; i++) {
            [_imageUrlArray addObject:array[i]];
            NSLog(@"nativePreviewImage-------图片数组-----%@",_imageUrlArray);
        }
        NSLog(@"[args lastObject]--------%@",[args lastObject]);
        NSString *str = [NSString stringWithFormat:@"%@",[args lastObject]];
        _index = [str integerValue];
        NSLog(@"_index-------%ld",_index);
        [self nativePreviewImageWithImageArray:_imageUrlArray index:_index];
    };
    
}
处理tabar中间按钮高于底部其他按钮部分不能点击
//重写hitTest方法,去监听发布按钮的点击,目的是为了让凸出的部分点击也有反应
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

    //这一个判断是关键,不判断的话push到其他页面,点击发布按钮的位置也是会有反应的,这样就不好了
    //self.isHidden == NO 说明当前页面是有tabbar的,那么肯定是在导航控制器的根控制器页面
    //在导航控制器根控制器页面,那么我们就需要判断手指点击的位置是否在发布按钮身上
    //是的话让发布按钮自己处理点击事件,不是的话让系统去处理点击事件就可以了
    if (self.isHidden == NO) {

        //将当前tabbar的触摸点转换坐标系,转换到发布按钮的身上,生成一个新的点
        CGPoint newP = [self convertPoint:point toView:self.plusBtn];

        //判断如果这个新的点是在发布按钮身上,那么处理点击事件最合适的view就是发布按钮
        if ( [self.plusBtn pointInside:newP withEvent:event]) {
            return self.plusBtn;
        }else{//如果点不在发布按钮身上,直接让系统处理就可以了

            return [super hitTest:point withEvent:event];
        }
    }

    else {//tabbar隐藏了,那么说明已经push到其他的页面了,这个时候还是让系统去判断最合适的view处理就好了
        return [super hitTest:point withEvent:event];
    }
}

关于上传代码到github
1、下载Git installer,地址:http://git-scm.com/downloads
2、pkg包下载完成,双击安装。
3、打开终端,使用git --version命令查看安装版本,能查看到就是安装成功了
接下来就是创建SSH。打开终端,输入以下命令来查看.ssh是否存在:

$ cd ~/.ssh  

若提示“-bash: cd: ~/.ssh: No such file or directory” 那就说明.ssh文件夹不存在,那么则进行下一个步骤,否则就是将原来的.ssh文件夹备份以下,亦或是切换到其他路径下建立ssh。输入以下命令来创建ssh:

$ ssh-keygen -t rsa -C xxx@xx.com  
xxx@xx.com为你注册GitHub时的邮箱账号。
注意:可以记事本打开ssh文件夹下你刚创建的公钥,私钥(ras_pub,rsa)查看里面是否有你的邮箱地址(可以通过这个验证自己是否创建成功)。

命令执行成功后,会有以下提示.(后面这几步都直接回车默认,修改路径可能会出现问题)
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/yuyuhang/.ssh/id_rsa): // .ssh默认路径,不输入则不修改
Enter passphrase (empty for no passphrase): // 密码长度至少为4,否则失败
Enter same passphrase again:
Your identification has been saved in /Users/yuyuhang/.ssh/id_rsa.
Your public key has been saved in /Users/yuyuhang/.ssh/id_rsa.pub.
The key fingerprint is:
8d:d3:5f:31:ae:13:48:f0:78:df:a1:8f:a5:a4:c0:06 352091626@qq.com
The key's randomart image is:
+--[ RSA 2048]----+
| . |
| + |
| E . + + |
| o * o + + |
| S + = = |
| . o + O |
| . * . |
| . |
| |
+-----------------+
以上创建成功。

测试链接

ssh -T git@github.com

Hi MiracleHe! You've successfully authenticated, but GitHub does not provide shell access.
连接成功!
如果出现错误提示:Permission denied (publickey).因为新生成的key不能加入ssh就会导致连接不上github。
解决办法如下:
1、先输入$ ssh-agent,再输入$ ssh-add ~/.ssh/id_key,这样就可以了。
2、如果还是不行的话,输入ssh-add ~/.ssh/id_key 命令后出现报错Could not open a connection to your authentication agent.解决方法是key用Git Gui的ssh工具生成,这样生成的时候key就直接保存在ssh中了,不需要再ssh-add命令加入了,其它的user,token等配置都用命令行来做。
3、最好检查一下在你复制id_rsa.pub文件的内容时有没有产生多余的空格或空行,有些编辑器会帮你添加这些的。

设置个人信息
$ git config --global user.name "Jone Zhang"
$ git config --global user.email [jonezhang86@gmail.com]
$ git config --global github.token f05df1f5bf94ce3215c9168c89bb9ae71213855a

接下来就是在GitHub上创建SSH。首先登陆你的GitHub,右上角用户头像下选择Settings,在SSH Keys 选项里面添加ssh,如下所示。


Title:随便填
Key:打开你生成的id_rsa.pub文件(终端输入$ open ~/.ssh ),将其中内容拷贝过来。
在Mac OSX下,隐藏文件默认是不显示的,可以通过以下命令来 显示/隐藏 隐藏文件夹

显示Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles YES  
隐藏Mac隐藏文件的命令:
defaults write com.apple.finder AppleShowAllFiles NO 

然后在GitHub上创建版本库(Repository),在GitHub首页上,点击“Create a New Repository”,如下所示(为了便于后面演示,创建README.md这步暂不勾选):



创建完成后跳转到代码仓库界面,如下:



当然了,在没有上传代码之前,列表是空的。
紧接着按照以下步骤进行本地仓库的创建及代码上传。打开终端,输入以下命令:

1.1.在gitHub上创建一个仓库,这个就不多说了,网上有很多。
2.在终端cd 到你要存放或者想要提交的文件夹(一般桌面)
3.终端输入git clone https://github.com/majunjie123/Test.git //后面的地址是你的github仓库地址 (桌面上会多一个Test文件夹),将所有你要上传的文件复制到该文件夹内(注意:不要在外面在包一层文件夹)
4.cd到Test文件夹下 执行git add .
5.终端执行git commit -m "直播播放器" 注释提交
6.终端执行git push -u origin master //到此你的文件就成功上传到github上了。

如果使用后台操作影响耗电(如后台定位等)需要在上传时告知用户,否则会被拒


Hello,

Call Ticket: 1519539

We have been trying to reach you at the number we have in our systems to discuss the app review results and have been unsuccessful.

At this time, we are now discontinuing the review of your binary. Your app has been rejected for the App Store Review Guideline detailed below.

Performance - 2.5.4


Your app uses the Location Background mode but still does not include the required "battery use" disclaimer in your app description.

Next Steps

Please add the following disclaimer to your Application Description:

"Continued use of GPS running in the background can dramatically decrease battery life."

Resources

Since your iTunes Connect Application State is Metadata Rejected, we do NOT require a new binary. To revise the metadata, visit iTunes Connect to select your app and revise the desired metadata values. Once you’ve completed all changes, reply to this message in Resolution Center and we will continue the review.

NOTE: Please be sure to make any metadata changes to all App Localizations by selecting each specific localization and making appropriate changes.

+++++++++++++++++++++++++
今天遇到个坑,ui爸爸只给了个图,没有给@2x和@3x。然后图片保护一直不成功,然后把图片改为@2x就好了,还是要注意细节啊。

//    CGFloat top = 300 ; // 顶端盖高度
//    CGFloat bottom = 300 ; // 底端盖高度
//    CGFloat left = 300; // 左端盖宽度
//    CGFloat right = 300; // 右端盖宽度
//    UIEdgeInsets insets = UIEdgeInsetsMake(top, left, bottom, right);
//    // 指定为拉伸模式,伸缩后重新赋值
//    UIImage *image1 = [UIImage imageNamed:@"red_BG"];
//    image1 = [image1 resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeStretch];
//    UIImageView* redImgView = [[UIImageView alloc] initWithImage:image1];
//    redImgView.frame = CGRectMake(30, 50, VIEW_WIDTH-60, VIEW_HEIGHT-100);
//    [self.view addSubview:redImgView];

客户端杀死状态下收到推送

    if(launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
        // 当被杀死状态收到本地通知时执行的跳转代码
        UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
        NSDictionary *infoDict = notification.userInfo;
        [self.delegate diaplayAlertWhenReceivePushInfo:infoDict];  
    }

UIView中的坐标转换
[http://blog.csdn.net/xuhuan_wh/article/details/8486337]

获取tabelview中一个正在播放的cell的位置
    if(scrollView ==self.table){
        if (wmPlayer==nil) {
            return;
        }
        
        if (wmPlayer.superview) {
            CGRect rectInTableView = [self.table rectForRowAtIndexPath:currentIndexPath];
            CGRect rectInSuperview = [self.table convertRect:rectInTableView toView:[self.table superview]];
            NSLog(@"rectInSuperview = %@",NSStringFromCGRect(rectInSuperview));
   
            if (rectInSuperview.origin.y<-self.currentCell.backgroundIV.frame.size.height||rectInSuperview.origin.y>kScreenHeight-kNavbarHeight-kTabBarHeight) {//往上拖动
                [self releaseWMPlayer];
                [self.currentCell.playBtn.superview bringSubviewToFront:self.currentCell.playBtn];
            }
        }
    }

计算lable中字的行数以及每行的内容

#import <CoreText/CoreText.h>
- (NSArray *)getLinesArrayOfStringInLabel:(UILabel *)label{
    NSString *text = [label text];
    UIFont *font = [label font];
    CGRect rect = [label frame];
    
    CTFontRef myFont = CTFontCreateWithName(( CFStringRef)([font fontName]), [font pointSize], NULL);
    NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:text];
    [attStr addAttribute:(NSString *)kCTFontAttributeName value:(__bridge  id)myFont range:NSMakeRange(0, attStr.length)];
    CFRelease(myFont);
    CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString(( CFAttributedStringRef)attStr);
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, CGRectMake(0,0,rect.size.width,100000));
    CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, NULL);
    NSArray *lines = ( NSArray *)CTFrameGetLines(frame);
    NSMutableArray *linesArray = [[NSMutableArray alloc]init];
    for (id line in lines) {
        CTLineRef lineRef = (__bridge  CTLineRef )line;
        CFRange lineRange = CTLineGetStringRange(lineRef);
        NSRange range = NSMakeRange(lineRange.location, lineRange.length);
        NSString *lineString = [text substringWithRange:range];
        CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attStr, lineRange, kCTKernAttributeName, (CFTypeRef)([NSNumber numberWithFloat:0.0]));
        CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attStr, lineRange, kCTKernAttributeName, (CFTypeRef)([NSNumber numberWithInt:0.0]));
        //NSLog(@"''''''''''''''''''%@",lineString);
        [linesArray addObject:lineString];
    }
    CGPathRelease(path);
    CFRelease( frame );
    CFRelease(frameSetter);
    return (NSArray *)linesArray;
}

ios 10+系统下推送遇到了这个问题,之前外包公司脑残残本地化选择了英文。(选择中文的话推送在通知栏是好的)



解决方法 在plist文件中添加了 Localized resources can be mixed YES
显示正常了。
————————————————————————————
arc环境下 定时器,通知,c语言对象需要relase。
————————————————————————————
关于加密:
rsa(非对称加密):适用小数据加密
des(对称加密):数据量比较大的加密
非对称加密可以和对称加密配合一起使用。
可以用对称加密 存储rsa(非对称加密)的key

des有ECB和CBC加密之分
https://zhidao.baidu.com/question/518688580.html

数字签名 :
将 数据+rsa(md5(数据))传递
验证:将数据md5 取出rsa里面被md5的数据对比 ,如果两个md5相比不一致则判断数据被修改,一致的话没有被修改。
——————————————————————————————
视图 锚点

position属性是决定子layer在父layer上的位置,默认为(0,0)。其次,anchorPoint属性是决定子layer上的哪个点会在position所指定的位置。
anchorPoint可以看作和position重合。(怎么说呢,就是好比position位置为(0,0),子layer的anchorPoint坐标为(0.5,0.5),那么(0.5,0.5)这个点就在父视图的(0,0)位置)
参考:http://m.blog.csdn.net/article/details?id=50981971

iOS10可以这样设置就可以转调 客户端跳转设置页面
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"App-Prefs:root=WIFI"]]; wifi iOS10可以这样设置就可以转调

一些小的点:
何谓运行时:
oc是动态语言,类型的判断、类的成员变量、方法的内存地址都是在程序的运行阶段才最终确定,并且还能动态的添加成员变量和方法。也就意味着你调用一个不存在的方法时,编译也能通过,甚至一个对象它是什么类型并不是表面我们所看到的那样,只有运行之后才能决定其真正的类型。相比于静态语言,动态语言具有较高的灵活性和可订阅性。而oc,正是一门动态语言。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容