2017-02-08 16:12:48 qq_31810357 阅读数 7010
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    7588 人正在学习 去看看 李文瀚


        从事iOS开发有些年月了,从最开始的磕磕绊绊,不知所措,到现在的遇到困难都能快速做出最佳方案处理,中间经历了不可或缺的痛苦。在项目开发中,本人有用印象笔记记录的习惯,所以很多重复出现的坑,很快迎刃而解,而不在同一个地方摔倒两次。为此,特意总结了一下开发中经常遇到的坑,有些可能和你形成共鸣,有些在你看来或许是小儿科,不喜勿喷。



1.XCode8的项目在xcode7运行报错:
The document “ViewController.xib” requires Xcode 8.0 or later. This version does not support documents saved in the Xcode 8 format. Open this document with Xcode 8.0 or later.

有两种方法解决这个问题

1.你同事也升级Xcode8,比较推荐这种方式,应该迎接改变。

2.右击XIB或SB文件 -> Open as -> Source Code,删除xml文件中下面一行字段。



2.场景:tabbar左右pan手势切换,其中一个VC是UIPageViewController,这样会导致到pageView的时候不能切换tabbar,如何禁掉pageVC切换呢?

出于UIPageViewController和UItableView等产生手势冲突,我们往往要禁用其翻页手势,代码如下:

self.pageViewController.dataSource = nil;

网络上搜到的重写手势等方法,亲测无效,所以给出这个最简单粗暴的方法。

// tabbar的切换动画(一般不用哦)

- (void)viewWillDisappear:(BOOL)animated

{
    [super viewWillDisappear:animated];    
    CATransition *transition = [CATransition animation];
    [transition setDuration:1];
    [transition setType:@"fade"];
    [self.tabBarController.view.layer addAnimation:transition forKey:nil];
}

// 解决带有轮播图的手势冲突
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    if (touch.view.frame.origin.y<100){
        
        return NO;
    }
    return YES;
}

//1,禁止.DS_store生成:
打开 “终端” ,复制黏贴下面的命令,回车执行,重启Mac即可生效。
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool TRUE

//2,恢复.DS_store生成:
defaults delete com.apple.desktopservices DSDontWriteNetworkStores

3.FMDB根据条件查询数据库出现的错误:

解决办法:




4.后台数据中出现空格特殊字符:

问题:注意选项A...我竟然匹配不到这种字符, \r\n\t都不行
方案:中文全角空格...你想说什么...我转了下...\u3000  已解决!




5.浮点型取整问题:


//Objective-C拓展了C,自然很多用法是和C一致的。比如浮点数转化成整数,就有以下四种情况。
//1.简单粗暴,直接转化

float f = 1.5; int a; a = (int)f; NSLog("a = %d",a);

//输出结果是1。(int)是强制类型转化,丢弃浮点数的小数部分。
//2.高斯函数,向下取整

float f = 1.6; int a; a = floor(f); NSLog("a = %d",a);
//输出结果是1。floor()方法是向下取整,类似于数学中的高斯函数 [].取得不大于浮点数的最大整数,对于正数来说是舍弃浮点数部分,对于复数来说,舍弃浮点数部分后再减1.

//3.ceil函数,向上取整。

float f = 1.5; int a; a = ceil(f); NSLog("a = %d",a);
//输出结果是2。ceil()方法是向上取整,取得不小于浮点数的最小整数,对于正数来说是舍弃浮点数部分并加1,对于复数来说就是舍弃浮点数部分.

//4.通过强制类型转换四舍五入。

float f = 1.5; int a; a = (int)(f+0.5); NSLog("a = %d",a);

6.关于block传值及数据同步总结:
A B C三个界面间C界面修改内容达到AB界面刷新最新的数据保持ABC数据同步:1.C到B可以用block回调传值 2.B界面到A界面只需在B界面Back的时候发出拉取数据并刷新cell即可解决数据不同步现象。


//在iOS开发过程中, 我们可能会碰到一些系统方法弃用, weak、循环引用、不能执行之类的警告。 有代码洁癖的孩子们很想消除他们, 今天就让我们来一次Fuck 警告!!

//首先学会基本的语句

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
//这里写出现警告的代码
#pragma clang diagnostic pop   //这样就消除了方法弃用的警告!

7.iOS8调用相机警告:
错误代码:Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or
snapshot after screen updates.
IOS8多了一个样式UIModalPresentationOverCurrentContext,
IOS8中 presentViewController时请将控制器的modalPresentationStyle设置为 UIModalPresentationOverCurrentContext,问题解决!!

8.错误点: ENABLE_BITCODE错误设置(mrc下)
解决方法:




// 默认选中第一行
[tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionNone];
// 实现了选中第一行的方法
[self tableView:_mainIndustryTableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
例如:
// 默认下选中状态
- (void)customAtIndex:(UITableView *)tableView
{
    // 默认选中第一行
    [tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionNone];
    if ([tableView isEqual:_mainIndustryTableView]) {
       [self tableView:tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
    }
}



9.iOS headerview与tableview之间距离控制?

//view 作为 tableView 的 tableHeaderView,单纯的改变 view 的 frame 是无济于事的,tableView  不会大度到时刻适应它的高度(以后 Apple 会不会改变就不知道了),
//所以,如何告诉tableView 它的 tableHeaderView 已经改变了?很简单,就一句话(关键最后一句):
[webView sizeToFit];
CGRect newFrame = headerView.frame;
newFrame.size.height = newFrame.size.height + webView.frame.size.height;
headerView.frame = newFrame;
[self.tableView setTableHeaderView:headerView];
 //这样以后,效果就出来了。不过这种过度显得有些生硬,能不能加一点点动画,让它变得顺眼一些呢?试试下面的代码:
[self.tableView beginUpdates];
[self.tableView setTableHeaderView:headerView];
[self.tableView endUpdates];



10.cell 分割线不全:

-(void)viewDidLayoutSubviews {
    if ([_listTableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [_listTableView setSeparatorInset:UIEdgeInsetsZero];
    }
    if ([_listTableView respondsToSelector:@selector(setLayoutMargins:)])  {
        [_listTableView setLayoutMargins:UIEdgeInsetsZero];
    }
   
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPat{
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]){
        [cell setSeparatorInset:UIEdgeInsetsZero];
    }
}

// 自绘分割线
- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
   
    CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
    CGContextFillRect(context, rect);
   
    CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:0xE2/255.0f green:0xE2/255.0f blue:0xE2/255.0f alpha:1].CGColor);
    CGContextStrokeRect(context, CGRectMake(0, rect.size.height - 1, rect.size.width, 1));
}



11.iOS7.0以后的UILabel会自动将Text行尾的空白字符全部去除,除了常见的半角空格(\0×20)和制表符(\t)之外,全角空格 (\u3000)也被计算在内,甚至连多余的换行符(\r\n)也被自动去除了。
这一点虽然方便直接将控件赋值和无需取值后再trim,但是太过智能化 了之后,往往不能满足一些本可以简单实现的需求。
需求1.使用添加\n方式将上下文本连续空两行,即实现文本的2倍行距。
iOS7.0
之前解决办法:在每个换行符后面添加一个空格
即如果要显示为:
aaaaaaa
空行
空行
bbbbbb
使用以下格式进行文本赋值
lbl.text = @"aaaaaaa\n\u0020\n\u0020bbbbbb";
iOS7.0
之后需要增加,不增加则无效
lbl.numberOfLines = 0; // 0
表示行数不固定
lbl.lineBreakMode=UILineBreakModeWordWrap; // 允许换行(可选)

需求2.在所有的UILabeltext后增加一个空格,并使text右对齐。
iOS7.0
之前解决办法:直接在text后增加空格即可,即text在赋值前增加空格。
lbl.text = [NSString stringWithFormat:@"%@%@","aaaaa","\u0020"];
iOS7.0之后需要重写UILabeldrawTextInRect方法,通过缩短默认文本绘制Rect的宽度半个字体宽度来实现。(当然也可以在底部铺一个view调整,暨简单又高效)
具体实现代码如下:

#import "MyLabel.h"
 
@implementation MyLabel
-(id) initWithFrame:(CGRect)frame { 
  self = [super initWithFrame:frame];
    if(self){
     return self;
    }   
}
 
-(void) drawTextInRect:(CGRect)rect {
  //从将文本的绘制Rect宽度缩短半个字体宽度
  //self.font.pointSize / 2
  return [super drawTextInRect:CGRectMake(rect.origin.x, rect.origin.y, rect.size.width - self.font.pointSize / 2, rect.size.height)];
}
@end
//附录: 
//UILabel会自动清除的空白字符(UNICODE) 
\u0009 CHARACTER TABULATION
\u000A LINE FEED
\u000D CARRIAGE RETURN
\u0020 SPACE
\u0085 NEXT LINE
\u00A0 NBSP
\u1680 OGHAM SPACE MARK
\u180E MONGOLIAN VOWEL SEPARATOR
\u2000 EN QUAD
\u200A HAIR SPACE
\u200B ZERO WIDTH SPACE
\u2028 LINE SEPARATOR
\u2029 PARAGRAPH SEPARATOR
\u202F NARROW NO-BREAK SPACE
\u205F MEDIUM MATHEMATICAL SPACE
\u3000 IDEOGRAPHIC SPACE 



12.监听UITextField的text的变化:

// 注册监听
    [[NSNotificationCenter defaultCenter]postNotificationName:UITextFieldTextDidChangeNotification object:nil];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(changeForKeyWord:) name:UITextFieldTextDidChangeNotification object:nil];
// 监听关键词变化
- (void)changeForKeyWord:(NSNotification *)sender
{
    // 关键词改变时清除地区查询条件纪录
    [[NSUserDefaults standardUserDefaults]setObject:@"0" forKey:@"proRow"];
    [[NSUserDefaults standardUserDefaults]setObject:@"0" forKey:@"section"];
}
//监听UITextField的点击事件
[[NSNotificationCenter defaultCenter]postNotificationName:UITextFieldTextDidBeginEditingNotification object:nil]; 
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(enterEdited:) name:UITextFieldTextDidBeginEditingNotification object:nil]; 
 
- (void)enterEdited:(NSNotification *)sender 
{ 
    //事件写这里!希望帮到你! 
} 

13.改变cell的选中颜色:

cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.frame];
cell.selectedBackgroundView.backgroundColor = COLOR_BACKGROUNDVIEW;
//不需要任何颜色可以这么设置:
cell.selectionStyle = UITableViewCellSelectionStyleNone;

14.旋转图片:

#pragma mark ----- 更新按钮动画
- (void)rotate360DegreeWithImageViews:(UIImageView *)myViews{
    CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 ];
    rotationAnimation.duration = 1.0;
    rotationAnimation.cumulative = YES;rotate360DegreeWithImageViews
    rotationAnimation.repeatCount = 100000;
    [myViews.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
}
[myViews.layer removeAllAnimations]; // 停止


15.UIView的exclusiveTouch属性:
通过设置[self setExclusiveTouch:YES];
可以达到同一界面上多个控件接受事件时的排他性,从而避免一些问题。

//1. 设置的时候在ib里面记得选择无边框的,要不然随便你设置,都是无效的,也是坑死了。
  _textBoxName.layer.borderWidth=1.0f;
    _textBoxName.layer.borderColor=[UIColorcolorWithRed:0xbf/255.0fgreen:0xbf/255.0fblue:0xbf/255.0falpha:1].CGColor;

//2.在uitextfield 中文字最左边距离左侧边框的距离
  _textBoxName.leftView=[[UIViewalloc] initWithFrame:CGRectMake(0,0, 16,51)];
  _textBoxName.leftViewMode=UITextFieldViewModeAlways;



16.当你使用 UISearchController 在 UITableView 中实现搜索条,在搜索框已经激活并推入新的 VC 的时候会发生搜索框重叠的情况:

解决办法:那就是 definesPresentationContext 这个布尔值。



17.画个曲线如何做呢?如图:

 UIView *myCustomView = [[UIView alloc]initWithFrame:CGRectMake(0, 204,kScreenWidth, 120)];
    myCustomView.backgroundColor = [UIColor whiteColor];
    [view addSubview:myCustomView];
   
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    [bezierPath moveToPoint:CGPointMake(0,0)];
    [bezierPath addCurveToPoint:CGPointMake(myCustomView.width, 0) controlPoint1:CGPointMake(0, 0) controlPoint2:CGPointMake(myCustomView.width/2, 40)];
    [bezierPath addLineToPoint:CGPointMake(myCustomView.width, myCustomView.height)];
    [bezierPath addLineToPoint:CGPointMake(0, myCustomView.height)];
    [bezierPath closePath];
   
    CAShapeLayer *shapLayer = [CAShapeLayer layer];
    shapLayer.path = bezierPath.CGPath;
    myCustomView.layer.mask = shapLayer;
    myCustomView.layer.masksToBounds = YES;



18.有效解决刷新单个cell或者section闪一下的问题:

[UIView setAnimationsEnabled:NO];
[_listTable beginUpdates];
[_listTable reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationNone];
[_listTable endUpdates];
[UIView setAnimationsEnabled:YES];


19.保持imageView 图片不变形:

_topImageView.contentMode = UIViewContentModeScaleAspectFit;


[__NSArrayI addObject:]: unrecognized selector sent to instance 
//当我创建了一个NSMutableArray 对象的时候
@property (nonatomic,copy)NSMutableArray *children;
//然后通过addObject运行就会报错,[__NSArrayI addObject:]: unrecognized selector sent to instance 
//解决方法:copy改成strong


20.Label后加小图标

NSMutableAttributedString *attri = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ ",fields.title]];
    // 添加表情
    NSTextAttachment *attch = [[NSTextAttachment alloc] init];
    // 表情图片
    attch.image = [UIImage imageNamed:@"newTopList"];
    // 设置图片大小
    attch.bounds = CGRectMake(10, 0, 25, 14);
    if ([fields.isnew boolValue]) {
        // 创建带有图片的富文本
        NSAttributedString *strings = [NSAttributedString attributedStringWithAttachment:attch];
        [attri appendAttributedString:strings];
    }
    // 用label的attributedText属性来使用富文本
    _titleLabel.attributedText = attri;


21.状态栏字体颜色及背景颜色调整

UIView *statusBarView=[[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 20)];
statusBarView.backgroundColor= [UIColor whiteColor];
[self.view addSubview:statusBarView];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:NO];


22.xib加载不同尺寸的屏幕如何控制宽高?

- (void)viewDidLoad {
    [super viewDidLoad];
   
    myView = [[MyView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 206)];
    [self.view addSubview:myView];
}
- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    //在这里计算尺寸
    myView.myView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 206);
}

// 或者修改如下:
   UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, kScreenWidth-48, 232)];//310
    GCVipGroupView *groupView = [[GCVipGroupView alloc]initWithFrame:view.frame andCollect:NO];
    groupView.delegate = self;
    groupView.bigView.frame = view.frame;
    [view addSubview:groupView];



 23.我的位置(强制获取):

MKMapItem *mylocation = [MKMapItem mapItemForCurrentLocation];
// 当前经纬度
float currentLatitude = mylocation.placemark.location.coordinate.latitude;
float currentLongitude = mylocation.placemark.location.coordinate.longitude;

// 默认位置(模拟器测试要注释掉才行)
[self setMapViewCenter:CLLocationCoordinate2DMake(currentLatitude, currentLongitude)];



24.比如弹框上放了scrollowView第一次弹出需要裁剪,滑动时需要显示下面的内容:

解决办法:让scrollowView的范围跟父视图同等高就解决了!


25.去除多余cell不管用怎么办:

self.searchResultTableView.tableFooterView = [[UIView alloc]init];
//或者加一个:    self.searchResultTableView.separatorStyle = UITableViewCellSeparatorStyleNone;



26.判断页面消失或出现时是push还是pop操作:

- (void)viewWillDisappear:(BOOL)animated {
    NSArray *viewControllers = self.navigationController.viewControllers;//获取当前的视图控制其
    if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
        //当前视图控制器在栈中,故为push操作
        NSLog(@"push");
    } else if ([viewControllers indexOfObject:self] == NSNotFound) {
        //当前视图控制器不在栈中,故为pop操作
        NSLog(@"pop");
    }
}


27.运行环境问题:

A valid provisioning profile for this executable was not found.
解决问题所在:发布证书无法运行在真机上!!!


更新关注:http://weibo.com/hanjunqiang  新浪微博!手机加iOS开发者交流QQ群: 446310206







2017-04-24 21:36:51 haharsw 阅读数 489
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    7588 人正在学习 去看看 李文瀚


题记

        最近有了个app创意,自然想把创意转换为财富——那就要把app做出来。iOS开发以前做过一点,没有深入过。不过对于高手来说,技术神马的都是相通的,那就在实践中强化自己的技术。在这篇文章中,我将记录自己开发过程中遇到的坑,记录一些零散的知识点,文章会不断更新。

正文

        1、综合众大神的观点,打算使用纯代码实现这个app,能不用storyboard就不用storyboard。工程刚刚建立完成,我便删掉了工程中的Main.storyboard 和 LaunchScreen.storyboard,然后再程序初始化的AppDelegate的didFinishLaunchingWithOptions函数中实现如下代码:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window = [[UIWindow alloc] init];
    UIViewController *tabBarVC = [[XXXTabBarController alloc] init];
    self.window.rootViewController = tabBarVC;
    
    [self.window makeKeyAndVisible];
    
    return YES;
}
但是运行程序的时候会发现程序的top和bottom两侧会有很大的黑色区域(为了对比,我把UIViewController中view的backgroundColor设置成了白色),也就是说程序实际上占用的区域只有中间一部分。尝试在iphone7、7plus、5的设备上运行都是一样的,通过NSLog输出 UIScreen mainScreen].bounds 会发现,输出的width和height分别是320、480,这个值是不对的。继续查看资料,通过把LaunchScreen.storyboard设置回来,问题就解决了。即在项目工程设置中的General>App Icons and launch Images>Launch Screen File设置成项目创建时生成的LaunchScreen.storyboard就可以了

        2、解决Xcode 的files missing from working copy警告。通过默认的工程创建,会有mian.m和APPDelegate类,我喜欢重新安排项目目录。重新安排main.m和AppDelegate类文件的目录后,Xcode会报files missing from working copy警告。这个警告实际上因为版本管理Git引起的,在创建项目之初,我选择了Create Git repository选项。找到了问题的原因,解决起来就好办了,只要在Xcode的Source Control 菜单下进行一下Commit操作就可以了。注意选中警告的文件。
 
        3、在编译工程的时候(尤其是下载而别人的工程),有时候会出现Apple Mach-O Linker Error(: Linker command failed with exit code 1 (use -v to see invocation))错误,但是又找不到具体的错误信息,很难解决这个连接错误。其实详细的错误信息可以在report navigator里找到。在现在xcode 8中,report navigator是8个navigator中最右侧的一个。
2016-07-27 11:36:55 xulefeng594 阅读数 197
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    7588 人正在学习 去看看 李文瀚

1 view的错误

用代码创建了一个view后能显示,但无法响应触摸事件
出错原因:可能是父view的frame为CGZero

2 cocoapods的更新

使用cocoapods更新库时,使用pod install无效。
出错原因:命令被墙 。
解决方法:pod install 换成pod install - -verbose - -no-repo-update这个命令

3 个人经验

mvc很重要!界面尽量用代码写!这样能保证关于界面样式相关的操作能封装在一个view中,而controller则集中于数据的处理操作。

4 关于MJRefresh

MJRefresh上拉/下拉刷新时,在xib/storyboard中不显示刷新控件
解放方法:

tableview.mj_header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(headRefresh)];
tableview.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(footRefresh)];

5 关于真机调试证书

【这次开发的过程是用了个人(XCode7后免费)、企业证书】
项目–>Team(此处用于选择证书用户)
①一般选择用户后会出现证书不匹配的问题,此时用fix解决即可。
②证书的profile配置的选择一般可以用com.XXX.*,这样就不必针对特定项目进行重新创建了。
③在Build Settings 里Code Siging Identiy里的Provisiong Profile选择Automatic即可。

6 特定设备出现的闪退问题

有时遇到的一些问题是只有特别设备才会出现的。

案例1
环境:
设备:macbook Pro 2015年版(13寸、8G+256闪存)
系统:macOS Sierra 10.12.2
XCode:8.2.1

情况:
使用UIEdgeInsets时并没有初始化,直接拿去使用。
导致出现如下问题:
{2.2847091420365001e-314, -20, 6.953210555402684e-310, nan}
其中nan显然是下溢。模拟器上导致并非一个数字,因此赋值时会崩溃。但在其它设备中并不会出现这种情况。

解决方法:
对UIEdgeInsets进行初始化
eg. UIEdgeInsets edgeInset = UIEdgeInsetsZero;

教训:
①每个设备的CPU、内存等都不同,对未初始化的属性赋值自然不同(使用不当可能会导致内存泄露)
②对局部变量需要进行初始化!!

iOS10开发哪些坑

阅读数 413

没有更多推荐了,返回首页