iOS开发常见问题

11.21常见问题

一storyboard连线问题

在这里插入图片描述
在这里插入图片描述

产生原因:将与storyboard关联的属性删除了,但是storyboard中还保持之前所关联的属性。
解决:

1.点击view controller

在这里插入图片描述

2.点击这排最后一个按钮

在这里插入图片描述

3.会出现

在这里插入图片描述

4.发现感叹号。点击感叹号的左边的x,取消关联就不会报错了。

二 文本框中怎么输入显示类似输入密码时候的东东。

解决:勾选这个
在这里插入图片描述

三.输入文本的时候,怎么显示右边的X按钮

1.点击

在这里插入图片描述

2.会显示

在这里插入图片描述

3.选择

在这里插入图片描述
表示当编辑的时候,会出出现X。
效果:
在这里插入图片描述

11.22 常见问题

一.Storyboard连线问题。

在这里插入图片描述
报错原因:1.没有实现btnClick这个方法。
解决方式一:添加这个btnClick这个方法
解决方式二:
1.点击view controller
在这里插入图片描述
2.点击这排最后一个按钮
在这里插入图片描述
3.会出现
在这里插入图片描述
4.发现感叹号没,和之前一样,x了它,就哦了。
注意点;OC中冒号也算做方法名的一部分喔,记住!

二.结构体问题

在这里插入图片描述
报错原因:OC语法规定:不允许直接修改某个对象的结构体属性的成员
_btn 是个对象
frame是个结构体。
对象和结构体是不一样的,结构体是C语言中的,里面可以定义许多属性,但是不能定义方法,而对象是即可以定义属性又可以定义方法的,是典型的面向对象语法。
如何改变对象中结构体属性的成员:
解决方法一:
// 既然不能直接修改对象中的结构体属性成员
// 先取出结构体
CGRect frame = _btn.frame;
// 修改结构体
frame.origin.y -= 10;
// 将修改后的结构体重新赋值回去
_btn.frame = frame;

解决方法二:
// 先取出y值
CGFloat y = _btn.frame.origin.y;
// 修改y值
y -= 10;
// 重新设置_btn的y值,其他属性和_btn保持不变
_btn.frame = CGRectMake(_btn.frame.origin.x, y, _btn.frame.size.width,_btn.frame.size.height);

三.Id问题

在这里插入图片描述
报错原因:id类型不能使用点语法
解决方式一:
// 利用get方法获取tag值
NSInteger i = [sender tag];

解决方式二:
// 将id强转为UIButton
UIButton *button = (UIButton *)sender;
// 就能使用点语法获取tag,编译器很笨的,他只会根据当前类型,去判断是否能使用这个语法。一般强转为对应类型,就能使用对应类型的方法了。
NSInteger i = button.tag;

四.如果发现给控件设置transform属性,控件没有任何反应,或者反应了,但是效果不对。

解决方法:将这个选项取消勾选。
在这里插入图片描述

五.如果想让同一个控件同时即改变位置的移动,又放大。这样设置是无效果的。

_btn.transform = CGAffineTransformMakeTranslation(0, 100);

_btn.transform = CGAffineTransformMakeScale(1.2, 1.2);

这样操作是创建新的transform然后赋值,给按钮的transform,第二次赋值的会把之前赋值的给覆盖,所以会达不到想要的效果。
解决方法:
_btn.transform = CGAffineTransformMakeTranslation(0, 100);
// 在之前的transform情况下,继续添加缩放的形变。
_btn.transform = CGAffineTransformScale(_btn.transform, 1.2, 1.2);

六.四舍五入问题。

float i = 1.7;
// 会自动四舍五入,不保留小数
NSLog(@"%0.f",i); // 打印结果2
// 强转类型不会四舍五入
int j = (int)i;
NSLog(@"%d",j); // 打印结果1

七.优先级问题

// int b = 2;
// int a = 4 * (b == 2? 1:2);
// NSLog(@"%d",a); 打印出4

// int a = 4 * b == 2? 1:2;
// NSLog(@"%d",a); 打印出2

// 由此得出 * 比 == 优先级高,先算*,在算==

八.模拟器黑屏

解决方法:
在这里插入图片描述

九.打代码时,Xcode没提示

解决方法:
0.点击Preferences
在这里插入图片描述

  1. 进入Text Editing
    在这里插入图片描述
  2. 勾选
    在这里插入图片描述

十.有的同学可能在勾选 Autolayout的时候,搞错了对象,误把控制器的View的User Interaction Enabled勾选掉了。

在这里插入图片描述
解决办法:User Interaction Enabled 必须勾选,否则控制器根视图中所有子控件无法进行任何操作。

在这里插入图片描述
在这里插入图片描述

11.23 常见问题

一.访问权限

错误:
在这里插入图片描述
会报链接错误。

在这里插入图片描述
报错原因,利用下划线访问了@package这个权限里的东西。
在这里插入图片描述
被@package 修饰的成员属性只能在同一个框架内部才允许访问。否则会引发link erro。
@private 实例变量只能被声明它的类访问
@protected 实例变量能被声明它的类和子类访问。
@public 实例变量可以被任何类访问。

11.24 常见问题

一.运行程序时,显示运行完成,但是模拟器没反应。

在这里插入图片描述
问题原因: 有时候应用程序的标示符一样,会导致程序不能成功运行。
解决方式一:将模拟器之前的程序删除。
解决方式二: 将模拟器还原

二.2d表示保留两位 02d 表示不够了 用0来补齐。

NSLog(@"%02d",cols);

三.Plist文件读取。

在这里插入图片描述
错误原因:不要看到有很多元素的,就认为是数组。
这样解析是错误的。
_dict = [NSArray arrayWithContentsOfFile:path];

这个pist文件是一个字典,正确的解析此plist文件。

// 2.根据文件路径加载字典
_dict = [NSDictionary dictionaryWithContentsOfFile:path];

四,给程序拖图片的时候,一定要注意,如下图勾选的,都要勾选中。

在这里插入图片描述

五.禁用UITextField的双击出现复制粘贴剪切等操作

解决方式:
有时候我们需要禁用UITextField的双击出现copy paste的功能,然而UITextField本身没有直接设置禁止用户复制粘贴剪切操作等方法,但是可以重载canPerformAction方法来实现。

新建一个类继承UITextField,然后实现canPerformAction方法:
只需覆盖canPerformAction:withSender方法就可以,canPerformAction:withSender属于UIResponder类的。
如下:
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender {

UIMenuController *menuController = [UIMenuController sharedMenuController];
if (menuController) {
[UIMenuController sharedMenuController].menuVisible = NO;
}
return NO;
}

11.25 常见问题

1.将UIButton添加到UILabel,UIButton是不能点击的。

原因: 1.UILabel是继承UIView的,默认不能监听点击事件。UIButton是继承UIControl能够监听点击事件。
2.将UIButton添加到UILabel,他们之间的关系是UILabel是UIButton的父视图,父视图都不能监听点击事件,自然而然不会将事件传递给子视图,因此UIButton也不能监听点击事件了。

思维指导:有些人会认为UIControl不是继承UIView的吗,都是继承UIView,为什么单独继承UIControl可以监听点击事件,继承UIControl的父类UIView不能监听事件了,这是因为我们一般在父类里实现的都是一些共用的属性和方法,而在子类中具体实现子类特有的方法。因此在UIControl实现了监听点击的特有方法,即继承UIControl才能监听点击事件。

2.发现不少人在给成员变量初始化的时候,容易进错一个方法去初始化。

注意这个方法只有在内存发生警告的时候才会调用。

  • (void)didReceiveMemoryWarning
    {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.

}
大部分成员属性的初始化应该在viewDidLoad里面进行。

  • (void)viewDidLoad
    {
    [super viewDidLoad];
    }

最牛解决方法:在一开始就将didReceiveMemoryWarning这个方法删掉。删掉不会影响程序运行。

3.模拟器问题

在这里插入图片描述
当出现这个问题的时候,原因:没有选择模拟器。
在这里插入图片描述
解决办法:
在这里插入图片描述

11.26常见问题

1.对象方法和类方法问题(此问题基础好的可以看看,基础稍微差的,可以先放着,以后回顾的时候,看看。)

// 创建视图的工厂方法
+ (UIView *)rowViewInitWithicon:(UIImage *)icon shuju:(NSString *)shuju
{
    rowView *viewtext = [[NSBundle mainBundle]loadNibNamed:@"rowView" owner:nil options:nil][0];
    [viewtext.btntouxiang setBackgroundImage:icon forState:UIControlStateNormal];
    viewtext.mingzilablexiao.text = shuju;
    
    // 重点是这句
    //  这是往通知中心添加一条通知 指定通知名称为  back  当观察者self监听到 back 通知是 就调用 callback
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callback) name:@"back" object:nil];
    
    /*   以下是报错信息:
     +[rowView callback]: unrecognized selector sent to class 0x79d8
     2013-11-26 15:31:02.581 lianxirenlianxi[1266:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[rowView callback]: unrecognized selector sent to class 0x79d8'
     */
    // reason: '+[rowView callback]: 看到报错原因里的+就想到没有实现callback这个类方法。
    
    // 由于self这个观察者是在类方法中添加的,指的是一个类,所以在调用方法的时候,他会去类方法中找有没有这个方法,不会去对象方法中找。因此我们也应该实现类方法。因此这里的self也只能调用类方法

// 由于实现的callback为对象方法  所以会报错
    //  解决方法  把callback  写成类方法   供观察者调用
    return viewtext;
}
//callback方法
- (void)callback
{
    NSLog(@"11111111111");
}

解决方法,将callback 写成类方法 供观察者调用
//callback方法
+ (void)callback
{
NSLog(@“11111111111”);
}

2.Xib是用来描述视图长什么样子,一个项目中允许有很多xib,因此我们需要给xib绑定一个标识,即他View中对应的class是谁,就代表描述哪个class。

在这里插入图片描述
Xib中owner的class是用来告诉xib中的View需要调用哪个对象的方法,就填谁。比如需要调用dog类中的方法,就填dog。
在这里插入图片描述
注意:在连线选择上别连错了,
步骤一:先考虑自己是想给视图添加控件了还是想给视图添加事件
步骤二:添加控件就跟xib中的view连线。添加一些事件就给xib中的File’s Owner 连线。

3.代码顺序问题

[UIView animateWithDuration:0.5 animations:^{
CGRect tmpFrame = sender.superview.frame;
tmpFrame.origin.x = self.view.frame.size.width;
sender.superview.frame = tmpFrame;
sender.superview.alpha = 0;
} completion:^(BOOL finished) {
int index = [self.view.subviews indexOfObject:sender.superview];
[sender.superview removeFromSuperview];
[UIView animateWithDuration:0.2 animations:^{
for (int i = index; i<self.view.subviews.count; i++)
{
UIView *chlid = self.view.subviews[i];
CGRect tmp = chlid.frame;
tmp.origin.y -=kViewH+1;
chlid.frame =tmp;
}

    }];
    // 在这判断删除按钮是否允许点中,会在动画执行完毕的时候,判断。
    _removeIteam.enabled = self.view.subviews.count>1;

}];
 // 而在执行代码块之外,判断删除按钮是否允许点中是不对的,因为动画是在后台运行的,所以在执行动画的时候,就已经执行完判断语句了,而这时最后一个视图还没销毁掉,因此删除按钮永远不会不允许选中,也就不能在判断删除按钮是否允许点中。

// _removeIteam.enabled = self.view.subviews.count>1;

删完最后一行之后,正确的效果。
在这里插入图片描述
删完最后一行之后,错误的效果。原因,判断的位置放错了。
在这里插入图片描述

4.Xib描述视图的时候,已经固定好描述视图的宽高了,外界调用视图的时候,只需要设置x,y值就好了

1.出现的问题,创建xib描述的视图时,将宽度设置为一个按钮的宽度了,导致删除按钮不能点击。
在这里插入图片描述

#pragma mark 添加联系人

  • (IBAction)AddPerson:(UIBarButtonItem *)sender {

    NSString *imgName=[NSString stringWithFormat:@“01%d.png”,arc4random_uniform(9)];
    NSString *labelName = arr[arc4random_uniform(arr.count)];
    RowView *rowView = [RowView rowViewWithIcon:imgName name:labelName];
    UIView *lastView = [self.view.subviews lastObject];
    int nextY = lastView.frame.origin.y + kSpace + kItemHW ;
    // 设置rowView的位置和尺寸
    CGRect cg =CGRectMake(0, nextY, kItemHW, kItemHW);
    rowView.frame=cg;

    [self.view addSubview:rowView];
    }
    错误原因:设置rowView的宽度为kItemHW,因此会有以上图片的出现。

错误会导致删除按钮不能点击,原因:父视图的尺寸不够,即父视图能接收事件的尺寸只有一点点,也就导致超出父视图尺寸的子视图不能监听点击事件。还有一点需要注意,将子视图添加到父视图尺寸之外的位置,只要还在屏幕上就会显示子视图,只不过它不能接收任何事件。
解决方法:CGRect cg =CGRectMake(0, nextY,rowView.frame.size.width , kItemHW);
这样设置就好了,因为xib里面已经设置了rowView的尺寸了,外界不需要更改视图的宽度了,直接获取视图的宽度即可。
正确效果:
在这里插入图片描述

5.UIToolBar问题

注意UIToolBar中不能使用viewWithTag这个方法,获取UIToolBar里的子视图。因为UIToolBar里的子视图都是UIBarButtonItem,而UIBarButtonItem是继承NSObject的,因此不能使用viewWithTag获取UIToolBar里的子视图,
viewWithTag:实现原理

  • (UIView *)viewWithTag:(NSInteger)tag
    {

// 1.如果当前tag和当前视图tag相同,直接返回
if (self.tag == tag) return self;

// 2.如果和当前视图tag不相同,遍历当前视图的所有子控件,查找对应的tag。

for (UIView *view in self.subviews) {
// 3.如果view不是UIView类或者UIView的子类直接返回nil
if (![view isKindOfClass:[UIView class]]) return nil;
if (tag == view.tag) {
// 4. 返回有相匹配的视图
return view;
}
}
// 5.如果都没有找到,返回nil.
return nil;
}

11.27常见问题

1.结构体和对象问题

// 这样定义是错的,结构体不是对象,声明变量是不需要加*
CGRect *frame = self.view.frame;
结构体变量正确定义:
CGRect frame = self.view.frame;
CGPoint center = self.view.center;
CGSize size = self.view.frame.size;

2.内存管理问题

错误打印:

在这里插入图片描述
正确打印:
在这里插入图片描述
当对象被销毁,一定会调用的方法,可以用这个方法,判断对象在什么时候销毁,用这个调试。
在这里插入图片描述

3.创建模型的时候,尽量自定义一个工厂方法供外界调用。

// 工厂方法,简化对象的实例化

  • (id)provinceWithName:(NSString *)name;

工厂方法好处:简化对象的实例化,快速创建对象。

4.非ARC内存管理问题。

有些同学在创建项目的时候忘记点ARC了,导致一些成员属性都莫名其妙的释放了。然后出现了一系列莫名其妙的错误。
在滚动UITableView的时候出现野指针错误。
在这里插入图片描述
一出现这些野指针错误,首先应该想到某些对象被释放了,然后发现代码中,并没有什么造成对象被释放的情况,这时候应该马上想到很可能是非ARC弄的。下图为怎么查看项目是否是非ARC。
在这里插入图片描述
在非ARC中没有强引用的概念,因此下图的成员变量是没有被强引用的。
在这里插入图片描述
在看看下图,allPro数组没有通过alloc调用,没有调用alloc产生的对象都是自动释放的

  allPro=@[
                @{
                    kCities:@[@"浦东",@"杨浦",@"闸北",@"闵行"],
                    kHeader:@"上海",
                    kFooter:@"上海不错"
                },
                @{
                    kCities:@[@"海淀",@"昌平",@"天安门"],
                    kHeader:@"北京",
                    kFooter:@"北京很好"
                 }
        
        ];

所以在滚动的时候会出现野指针错误,因此需要将项目改成ARC。如下图
在这里插入图片描述
在这里插入图片描述
两个勾都得选中,然后一直点确认就OK了。

6.数据模型属性采用的策略中除了基本类型需要用assign,字符串需要用copy,其他对象类型都需要用strong。而控制器中视图采用的策略需要根据情况而定。

下图就是数据模型中属性用错了策略导致,UITableViewcell重新出现到界面时,会导致数据丢失。
在这里插入图片描述

11.29 常见问题

1.想在点击cell时做些操作,方法选错了。

下面两个方法太相似了,很容易选错。
// 当点击一行cell时,会调用这个方法
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
// 当取消选择一行cell时,会调用这个方法
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath

2.字符串小调试技巧

当把一个字符串转换成基本数据类型时,字符串打印有值,但是转换成基本数据类型为0时,这个莫名其妙的问题,首先应该想到字符串中很可能有换行符合等,导致转换不成功。
在这里插入图片描述
NSString *str = @" 123";
NSInteger i = [str integerValue];
NSLog(@"%@",str);
NSLog(@"%d",i);
碰到这种情况,可以在打印字符串的时候在占位符两边各加一个数字.
NSLog(@“1%@1”,str);
然后看打印结果就能知道有字符串中有多少空行了
在这里插入图片描述
只要将空行去掉就能转换成功了。
字符串去掉空格的方法
// 此方法是通过什么字符集裁剪字符串。

  • (NSString *)stringByTrimmingCharactersInSet:(NSCharacterSet *)set;

NSCharacterSet对象可以通过类方法创建
// 创建空格和换行字符集
[NSCharacterSet whitespaceAndNewlineCharacterSet];
// 创建空格字符集
[NSCharacterSet whitespaceCharacterSet];

3.下图的警告意思是:初始化时,类型指向不匹配,应该用NSArray * 而不是YZPerson *

在这里插入图片描述

找到原因后,然后看person方法是怎么声明。
在这里插入图片描述
解决方式:将NSArray * 改成id。

11.30 常见问题

1.UITableView数据源问题

1.1
在这里插入图片描述
错误原因:说YZViewController 没有实现 tableView:numberOfRowsInSection:
解决方式:实现tableView:numberOfRowsInSection:

1.2
在这里插入图片描述
这里返回空,会报错。
UITableView内部实现原理:
数据源实现了这个方法
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

tableView内部自动会调用以下方法添加cell。
[tableView addSubview:cell];

如果返回的cell为空,也就意味着生成下面一行代码。
[tableView addSubview:nil];
而addSubview是将右边参数添加到数组中保存起来,而数组是不能添加空值的。所有集合对象都不能出传空。例如数组,字典,NSSet。

以上错误总结:作为tableView的数据源必须实现两个方法。
返回行数
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section;
返回每一行显示的内容
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
另外返回每一行显示的内容不能返回nil。

2.在数组删除一个模型,并不代表把这个模型给释放了。

在这里插入图片描述
上面步骤二,仅仅是将模型从数组中销毁,而模型并没有被销。

12.1 常见问题

1.stroyboard中显示的跟根视图是UIView,而stroyboard的控制器是UITableViewController就会报这个错误

在这里插入图片描述
原因是:UITableViewController控制器不能加载UITableView,因为它会去加载stroyboard中的UIView。
解决方式:将stroyboard中的UIView改成UITableView

12.2 常见问题

1.自定义视图的属性命名冲突问题

在这里插入图片描述
当发现自己描述的xib和运行的时候展现出来的不一样的时候,这时候已经想到自己命名的属性名称和系统命名的冲突了。

错误原因
在这里插入图片描述
系统自带的UITableViewCell中也有imageView这个属性,因此冲突了。
解决办法:将自定义视图的imageView属性名称改成iconView.
注意:以后自定义属性命名不要和系统自带的属性名称相同。

2.链接错误

在这里插入图片描述
以后看到duplicate这个词语,错误原因就是重复定义了类,函数方法等等。
一般都是因为导入了.m文件
错误:
在这里插入图片描述
解决方式:将#import "newsCell.m"这一行删掉。

3.注意将之前storyboard中控制器删除之后,拖入一个新的控制器的时候,stroyboard中控制器的class也要重新填入自己想要展示的控制器,告诉stroyboard去加载哪个控制器。

在这里插入图片描述

12.3常见错误

1.初始化方法命名规范问题。

在这里插入图片描述
看见这个错误,应该要想到初始化方法命名错误的问题。因为self只能在init开头的方法中赋值,init必须是一个独立的单词,因此init后的第一个字母必须大写。

12.4常见错误

1.重写set方法忘记赋值,以后重写set方法,第一步就先赋值。

2.strong和weak乱用

一般情况:代理和控件使用weak
其他对象使用strong
基本数据类型 使用assign

12.5常见错误

1.QQ好友列表中,展开了列表,但是箭头没动画。

原因:由于代理方法中重新刷新了表格,也就意味着把之前的头部视图给替换了,因此没有动画了,不要创建新的头部,才能让旧的头部执行动画
解决方法:用一个数组或者字典保存所有的头部视图,重新刷新的时候,直接取就OK了。

12.6 常见错误

1.加载xib时,名字是分大小写的,注意名字一定要保持一致。

在这里插入图片描述
报错原因:xib是大写的KeyboardTool,而加载的时候名字写成小写了。
解决方式:将加载的xib的名称改成大写。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值