产生缘由:将与storyboard关联的属性删除了,可是storyboard中还保持以前所关联的属性。数组
解决:app
解决:勾选这个框架
1.点击dom
2.会显示函数
3.选择 ,表示当编辑的时候,会出出现X。动画
效果:spa
报错缘由: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类型不能使用点语法
解决方式一:
// 利用get方法获取tag值
NSInteger i = [sender tag];
解决方式二:
// 将id强转为UIButton
UIButton *button = (UIButton *)sender;
// 就能使用点语法获取tag,编译器很笨的,他只会根据当前类型,去判断是否能使用这个语法。通常强转为对应类型,就能使用对应类型的方法了。
NSInteger i = button.tag;
解决方法: 将这个选项取消勾选。
_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
// 由此得出 * 比 == 优先级高,先算*,在算==
解决方法:
解决方法:
1. 进入Text Editing
2. 勾选
解决办法:User Interaction Enabled 必须勾选,不然控制器根视图中全部子控件没法进行任何操做。
错误:
会报连接错误。
报错缘由,利用下划线访问了@package这个权限里的东西。
被@package 修饰的成员属性只能在同一个框架内部才容许访问。不然会引起link erro。
@private 实例变量只能被声明它的类访问
@protected 实例变量能被声明它的类和子类访问。
@public 实例变量能够被任何类访问。
问题缘由: 有时候应用程序的标示符同样,会致使程序不能成功运行。
解决方式一:将模拟器以前的程序删除。
解决方式二: 将模拟器还原
NSLog(@"%02d",cols);
错误缘由:不要看到有不少元素的,就认为是数组。
这样解析是错误的。
_dict = [NSArray arrayWithContentsOfFile:path];
这个pist文件是一个字典,正确的解析此plist文件。
// 2.根据文件路径加载字典
_dict = [NSDictionary dictionaryWithContentsOfFile:path];
解决方式:
有时候咱们须要禁用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;
}
缘由: 1.UILabel是继承UIView的,默认不能监听点击事件。UIButton是继承UIControl可以监听点击事件。
2.将UIButton添加到UILabel,他们之间的关系是UILabel是UIButton的父视图,父视图都不能监听点击事件,天然而然不会将事件传递给子视图,所以UIButton也不能监听点击事件了。
思惟指导:有些人会认为UIControl不是继承UIView的吗,都是继承UIView,为何单独继承UIControl能够监听点击事件,继承UIControl的父类UIView不能监听事件了,这是由于咱们通常在父类里实现的都是一些共用的属性和方法,而在子类中具体实现子类特有的方法。所以在UIControl实现了监听点击的特有方法,即继承UIControl才能监听点击事件。
注意这个方法只有在内存发生警告的时候才会调用。
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
大部分红员属性的初始化应该在viewDidLoad里面进行。
- (void)viewDidLoad
{
[super viewDidLoad];
}
最牛解决方法:在一开始就将didReceiveMemoryWarning这个方法删掉。删掉不会影响程序运行。
当出现这个问题的时候,缘由:没有选择模拟器。
解决办法:
// 建立视图的工厂方法
+ (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");
}
Xib中owner的class是用来告诉xib中的View须要调用哪一个对象的方法,就填谁。好比须要调用dog类中的方法,就填dog。
注意:在连线选择上别连错了,
步骤一:先考虑本身是想给视图添加控件了仍是想给视图添加事件
步骤二:添加控件就跟xib中的view连线。添加一些事件就给xib中的File’s Owner 连线。
[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;
删完最后一行以后,正确的效果。
删完最后一行以后,错误的效果。缘由,判断的位置放错了。
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的尺寸了,外界不须要更改视图的宽度了,直接获取视图的宽度便可。
正确效果:
注意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;
}
// 这样定义是错的,结构体不是对象,声明变量是不须要加*
CGRect *frame = self.view.frame;
结构体变量正肯定义:
CGRect frame = self.view.frame;
CGPoint center = self.view.center;
CGSize size = self.view.frame.size;
错误打印:
正确打印:
当对象被销毁,必定会调用的方法,能够用这个方法,判断对象在何时销毁,用这个调试。
// 工厂方法,简化对象的实例化
+ (id)provinceWithName:(NSString *)name;
工厂方法好处:简化对象的实例化,快速建立对象。
有些同窗在建立项目的时候忘记点ARC了,致使一些成员属性都莫名其妙的释放了。而后出现了一系列莫名其妙的错误。
在滚动UITableView的时候出现野指针错误。
一出现这些野指针错误,首先应该想到某些对象被释放了,而后发现代码中,并无什么形成对象被释放的状况,这时候应该立刻想到极可能是非ARC弄的。下图为怎么查看项目是不是非ARC。
在非ARC中没有强引用的概念,所以下图的成员变量是没有被强引用的。
在看看下图,allPro数组没有经过alloc调用,没有调用alloc产生的对象都是自动释放的
allPro=@[
@{
kCities:@[@"浦东",@"杨浦",@"闸北",@"闵行"],
kHeader:@"上海",
kFooter:@"上海不错"
},
@{
kCities:@[@"海淀",@"昌平",@"天安门"],
kHeader:@"北京",
kFooter:@"北京很好"
}
];
因此在滚动的时候会出现野指针错误,所以须要将项目改为ARC。以下图
两个勾都得选中,而后一直点确认就OK了。
下图就是数据模型中属性用错了策略致使,UITableViewcell从新出现到界面时,会致使数据丢失。
下面两个方法太类似了,很容易选错。
// 当点击一行cell时,会调用这个方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
// 当取消选择一行cell时,会调用这个方法
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
当把一个字符串转换成基本数据类型时,字符串打印有值,可是转换成基本数据类型为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];
找到缘由后,而后看person方法是怎么声明。
解决方式:将NSArray * 改为id。
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。
上面步骤二,仅仅是将模型从数组中销毁,而模型并无被销。
缘由是:UITableViewController控制器不能加载UITableView,由于它会去加载stroyboard中的UIView。
解决方式:将stroyboard中的UIView改为UITableView
当发现本身描述的xib和运行的时候展示出来的不同的时候,这时候已经想到本身命名的属性名称和系统命名的冲突了。
错误缘由
系统自带的UITableViewCell中也有imageView这个属性,所以冲突了。
解决办法:将自定义视图的imageView属性名称改为iconView.
注意:之后自定义属性命名不要和系统自带的属性名称相同。
之后看到duplicate这个词语,错误缘由就是重复定义了类,函数方法等等。
通常都是由于导入了.m文件
错误:
解决方式:将#import "newsCell.m"这一行删掉。
看见这个错误,应该要想到初始化方法命名错误的问题。由于self只能在init开头的方法中赋值,init必须是一个独立的单词,所以init后的第一个字母必须大写。
通常状况:代理和控件使用weak
其余对象使用strong
基本数据类型 使用assign
缘由:因为代理方法中从新刷新了表格,也就意味着把以前的头部视图给替换了,所以没有动画了,不要建立新的头部,才能让旧的头部执行动画
解决方法:用一个数组或者字典保存全部的头部视图,从新刷新的时候,直接取就OK了。
报错缘由:xib是大写的KeyboardTool,而加载的时候名字写成小写了。
解决方式:将加载的xib的名称改为大写。