1.控件上数据没有的原因
a.源头数据是否存在
b.源头数据存在时,如果涉及到if比较,源头数据与被比较条件 是否存在匹配关系。
c.若1.2都OK,且控件数据先显示,最终又没有现实。此时定是有 2次调用 给控件赋值的方法。——>> (self.tableView reloadData)
2.EXC_BAD_ACCESS报错
EXC_BAD_ACCESS坏内存访问,野指针访问
__unsafe_unretained同样是assign的引用(MRC中没有weak)
在MRC中如果要弱引用对象都是使用assign,不会增加引用计数,但是一旦对象被释放,地址不会改变,继续访问,就会出现野指针访问。
在ARC weak,本质上是一个观察者,一旦发现对象被释放,会自动将地址置为nil,更加安全。
效率:weak的效率会略微差一些!!!!
3.友盟第三方分享出现的错误
友盟友盟第三方分享sdk及官方文档:(里面有 常见问题)
http://dev.umeng.com/social/ios/quick-integration#2_1
a.没有走 else里的方法————>>>原因是在appDelegate中未 设置系统回调函数(建议写前2个方法,不行3个都写进去)
[[UMSocialManagerdefaultManager]getUserInfoWithPlatform:UMSocialPlatformType_SinacurrentViewController:nilcompletion:^(idresult,NSError*error) {
if(error) {
NSLog(@"error:%@",error.description);
}else{
NSLog(@"微博登录成功");
UMSocialUserInfoResponse*resp = result;
//授权信息
NSLog(@"Sina uid: %@", resp.uid);
NSLog(@"Sina accessToken: %@", resp.accessToken);
NSLog(@"Sina refreshToken: %@", resp.refreshToken);
NSLog(@"Sina expiration: %@", resp.expiration);
//用户信息
NSLog(@"Sina name: %@",resp.name);
NSLog(@"Sina iconurl: %@", resp.iconurl);
NSLog(@"Sina gender: %@", resp.gender);
//第三方平台SDK源数据
NSLog(@"Sina originalResponse: %@", resp.originalResponse);
}
}];
b.走了 else里的方法————>>>报错:app受未审核通过的使用限制(引用受限).
error:Error Domain=applications over the unaudited use restrictions! Code=21321 "(null)”.UserInfo={error=applications over the unaudited use restrictions!, error_code=21321, request=/2/users/show.json}
http://blog.csdn.net/bingqingsuimeng/article/details/51505753
c.新浪微博、微信、QQ 分享按钮
新浪微博报错按钮点击——————>>Error Domain=UMSocialPlatformErrorDomain Code=2003 "(null)" UserInfo={message=Share fail}你的图片没有提供,可以用本地图片试试。
解决方案:(网上参考)
http://www.jianshu.com/p/ffd036435e9a
UMShareWebpageObject*shareObject = [UMShareWebpageObjectshareObjectWithTitle:@"分享标题"descr:@"分享内容描述"thumImage:[UIImageimageNamed:@"UMIcon"]];
(sdk默认图片@“Icon”,这里我修改为 本地的图片@“UMIcon”)
d.判断是否安装 微信 微博 新浪微博>>>>>>>>>>下面的3个文件实现了很多功能
iOS 社会化组件SDK v6.2.1(2017-1-6)最新的SDK已经集成好方法
#import“WeiboSDK.h” ————>>微博 这里有许多实用的方法
+ (BOOL)isWeiboAppInstalled;
#import“WXApi.h”————>>微信 这里有许多实用的方法
+(BOOL) isWXAppInstalled;
#import“QQApiInterface.h”————>>微信 这里有许多实用的方法
+ (BOOL)isQQInstalled;
4.当 通过请求数据 设置UI——>>达不到效果时
a.确认UI创建没有问题
b.数据有问题 排查方法 {
1.最好每一层数据请求 把它NSLog出来
2.通过NSLog 出来 找到 数据为null的 相应层
3.排查 接口的参数是否 正确, 接口的参数是否 有值
4.若没有值 继续往上一层排查 对应的参数
}
c.养好NSLog习惯,一层一层保证数据畅通。
5.NSMutableArray遍历删除注意事项(上品珍选2期—>>我的收藏—>>MyWishlistViewController.m—>>pushCancleWishlistAlert—>>UIAlertAction*sure—>// b.UI删除(跟新对应的cell))
http://blog.csdn.net/mingerw/article/details/51207158
工程中使用的是这个方法——>解决了问题
将要删除的字符串所在的下表添加在一个NSMutableIndexSet 中,最后一起删除
NSMutableArray*arr1 = [[NSMutableArrayalloc]initWithObjects:@"QQQ",@"ABC",@"DEF",@"ABC",@"ABC",@"QWE",@"TTT",nil];
NSMutableIndexSet*set = [[NSMutableIndexSetalloc]init];
for(inti =0; i < arr1.count; i++)
{
NSString*str = arr1[i];
if([strisEqualToString:@"ABC"])
{
[setaddIndex:i];
}
}
[arr1removeObjectsAtIndexes:set];
6.微信 朋友圈的第三方分享——>分享不出去原因之一
[message setThumbData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[shareDic objectForKey:@"miniPicUrl"]]]];
后台数据返回的 图片NSURL对应的图片>32k
7.帐号登录或快捷登录——>没有网络的处理
// LoginViewController.m
// smarthome
//自定义注册登录界面VC
//点击"登录按钮"
- (void)doLogin:(UIButton*)sender {
//判断网略状态(没有网:结束有网:进行)(2期新增)
NSIntegernetworkState = [self.googleReachcurrentReachabilityStatus];
if (networkState ==0) {
UIAlertController*alert = [MyAlertalertControllerTitle:@""message:@"连接失败"];
[selfpresentViewController:alertanimated:YEScompletion:nil];
return;
}
// 1.得到拼接的url取出machineCode等参数
NSArray*urlArr = [selfsetupLoginURLStr];
(重新调用这个方法 是为了使@"networkType":urlArr[1],有值,不然直接取nil会崩溃)
…….
}
8.收到极光registration id的方法——>没网运行app不会调用下面的方法(极光本身会检测网络状况)有网后会调用下面的方法:返回极光 且登录时 会调用跟新逻辑
[JPUSHServiceregistrationIDCompletionHandler:^(intresCode,NSString*registrationID) {
if(resCode ==0){
NSLog(@"registrationID获取成功:%@",registrationID);
JPushregistrationID= registrationID;
NSLog(@"7777777JPushRegisterID:%@",JPushregistrationID);//测试OK
// 2.存本地
[[NSUserDefaultsstandardUserDefaults]setObject:JPushregistrationIDforKey:JPushID];
[[NSUserDefaultsstandardUserDefaults]synchronize];
// 3.跟新极光token接口
//判断是否登录(已登录:跟新未登录:不做处理)
BOOLisLogin = [MyStringisOnline];
if (!isLogin) {
}else {
//"极光推送token更新"(新增)接口
[selfupdateJPushTokenWith:registrationID];
}
}
else{
NSLog(@"registrationID获取失败,code:%d",resCode);
}
}];
9.cell复用——>>1.超出屏幕会复用 2.已经创建过的cell会复用——>>所以涉及到数据(UI)的都要写在外面,这样reloadData才会渲染界面.
UITableViewCell*cell = [tableViewdequeueReusableCellWithIdentifier:@"CELL"];
if(cell ==nil) {
cell = [[UITableViewCellalloc]initWithStyle:UITableViewCellStyleValue1reuseIdentifier:@"CELL"];
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle=UITableViewCellSelectionStyleNone;
}
switch(indexPath.section) {//定时护眼分区
case0: {
//定时护眼的开关状态
BOOLswitchState = [xxSettingModel.protect_eye_timeintegerValue];
if(indexPath.row==0) {//定眼保护
cell.textLabel.text=NSLocalizedString(@"定眼保护",nil);
cell.accessoryType=UITableViewCellAccessoryNone;
UISwitch*s = [UISwitchnew];
s.tag=200;
if(xxSettingModel.protect_eye_time==NULL||xxSettingModel.protect_eye_time==nil) {
xxSettingModel.protect_eye_time=@"0";
}
s.on= switchState;
[saddTarget:selfaction:@selector(switchChanged:)forControlEvents:UIControlEventValueChanged];
cell.accessoryView= s;
}
…...
10.[UIImage imageWithData:]返回nil
使用目的:利用imageWithData这个二进制方法主要是为了得到一个图片对象。
使用场景:
1.NSString*path = [[NSBundlemainBundle]pathForResource:@"xxx.png"ofType:nil];
NSData*data = [NSData dataWithContentsOfFile:path];
由方法1而得到的data数据,经由[UIImageimageWithData:data]方法后,一定能得到一个图片对象。
方法1中xxx.png本来就是一个图片,故生成的data也是一个图片二进制。
2.NSData*data = [NSDatadataWithContentsOfURL:[NSURLURLWithString:imageUrlStr]];
[UIImageimageWithData:data]方法后,并不一定得到一个图片对象。
方法2中如果网络地址是一个纯图片的话,生成的data也是一个图片二进制,可以得到一个图片对象但是,网络地址是一个网页的话,生成的data不是有一个纯图片的二进制,姑图片对象为空。
解决方法:
对于方法2,1.在网络不好时,可能请求的图片数据不完整,image可能为nil;
2.网络地址是一个网页的话,生成的data不是有一个纯图片的二进制,可能图片对象为空。
所以这里需要做容错处理
//1.下载图片
NSURL *url = [NSURL URLWithString:modle.icon];
NSData *data = [NSData dataWithContentsOfURL:url];
BOOLisValidPNG = [selfisValidPNGByImageData:data];
if(isValidPNG) {
UIImage *image = [UIImage imageWithData:data];
...
}else{
return;
}
/**
*校验图片是否为有效的PNG图片
*
*@paramimageData图片文件直接得到的NSData对象
*
*@return是否为有效的PNG图片(JPG的请使用UIImageJPEGRepresentation方法)
**/
-(BOOL)isValidPNGByImageData:(NSData *)imageData {
UIImage *image = [UIImage imageWithData:imageData];
//第一种情况:通过[UIImage imageWithData:data];直接生成图片时,如果image为nil,那么imageData一定是无效的
if(image ==nil|| imageData ==nil) {
returnNO;
}
//第二种情况:图片有部分是OK的,但是有部分坏掉了,它将通过第一步校验,那么就要用下面这个方法了。将图片转换成PNG的数据,如果PNG数据能正确生成,那么这个图片就是完整OK的,如果不能,那么说明图片有损坏
NSData *tempData = UIImagePNGRepresentation(image);
if(tempData ==nil) {
returnNO;
}else{
returnYES;
}
}
11.iOS开发79-Xcode报错:The file “XXX” couldn’t be opened because you don’t have permission to view it.的解决方法
http://blog.csdn.net/nathan1987_/article/details/52314641
12.指针指向不兼容————>>类型转换
Incompatible pointer types assigning to 'NSString *' from 'GDataXMLNode *’
不兼容的指针类型从'GDataXMLNode *'分配给'NSString *'
13.CGAffineTransform————>>旋转注意点———>>具体代码见工程
1.动画的使用(1.旋转角度 2.实现位置的移动 3.加手势等)
[UIViewanimateWithDuration:0.25animations:^{
playerLayer.transform=CATransform3DMakeRotation(M_PI_2,0,0,1);
playBTN.transform=CGAffineTransformMakeRotation(M_PI_2);
}completion:^(BOOLfinished) {
playBTN.sd_layout
.bottomSpaceToView(self.view,kScreenHeight-64-30)
.leftSpaceToView(self.view,20)
.heightIs(60)
.widthIs(60);
playBTN.alpha=0;
volumeSlider.alpha=0;
videoSlider.alpha=0;
if(tapGR==nil) {
tapGR= [[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(videoTapAction:)];
touchNum=0;
}
[self.viewaddGestureRecognizer:tapGR];
}];
2.playBTN.transform=CGAffineTransformMakeRotation(M_PI_2)方法:
a.参数:需要传入的是一个角度(CGFloat angle)
M_PI = 180M_PI_2 = 90M_PI_4 = 45 0 = 0
#define M_PI3.14159265358979323846264338327950288/* pi */
#define M_PI_21.57079632679489661923132169163975144/* pi/2 */
#define M_PI_40.785398163397448309615660845819875721/* pi/4 */
b.先后执行。(里面的角度 指的是控件 要旋转到 的角度) (旋转的方向是 顺时针)
CGAffineTransformMakeRotation(M_PI_2) 顺时针旋转到90度
CGAffineTransformMakeRotation(0) 瞬时间旋转到0度,也就是到360(控件经过2次旋转后 又回到了最初的位置,相当于没有旋转)
c.当旋转后不知道控件 位置变化的规则时 ————>不妨先得到控件的 相对控件(self.view)的顶点位置
playBTN.sd_layout
.bottomSpaceToView(self.view,0)
.leftSpaceToView(self.view,0)
.heightIs(60)
.widthIs(60);
d.视频播放界面旋转———>>这里通过旋转视频播放器的AVPlayerLayer层并改变frame的大小实现全屏幕和小屏幕
所以 VC.view并没有旋转,其它控件利用自动布局 距上 距下 距左 距右(这里相对控件是VC.view)仍然是 原先VC.view竖屏幕的view,因为它没有转。
3.获取当前屏幕方向:orientation= [UIDevicecurrentDevice].orientation;
typedefNS_ENUM(NSInteger, UIDeviceOrientation) {
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait,// Device oriented vertically, home button on the bottom
UIDeviceOrientationPortraitUpsideDown,// Device oriented vertically, home button on the top
UIDeviceOrientationLandscapeLeft,// Device oriented horizontally, home button on the right
UIDeviceOrientationLandscapeRight,// Device oriented horizontally, home button on the left
UIDeviceOrientationFaceUp,// Device oriented flat, face up
UIDeviceOrientationFaceDown// Device oriented flat, face down
}__TVOS_PROHIBITED;
14.init初始化方法和set 与 get
先执行初始化方法
再执行set 与 get方法(因为都需要先创建 实例才能通过事例 调用其方法)
15.uiview里添加view类型的控件——>userInterfaceEnabled = YES必须打开用户交互
现象:当继承自uiview的控件里 添加subview,subview的交互无法起作用时,父视图uiview的交互必须打开。
16.init初始化方法和set 与 get方法 viewDidload方法————>>与14点的区别
1.先执行初始化方法
2.再执行set 与 get方法(如果set方法中想给属性控件赋值,而属性控件又在viewDidload中创建,此时赋值会不成功)
3.最后执行viewDidload方法(直接调用带有数据的 set和get方法即可)
17.UITableview点击2次才跳转
现象:cell第一次点击的时候是选中一行,等点击第二次的时候才会跳转。
原因:错用成了这个函数
- (void)tableView:didDeselectRowAtIndexPath:
而正确的应该是这
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
补充:若使用- (void)tableView:didDeselectRowAtIndexPath:
传过去的是上一次点击没有跳转的那个cell的信息。
哈哈哈哈----------
18.字符串为空的处理
NSString*device_version = [self.infoDicobjectForKey:@"device_version"];
if([device_versionisEqual:[NSNullnull]]|| device_version ==nil|| device_version.length==0) {
device_version =@"家居版";
}
cell.detailTextLabel.text= device_version;
18.基本数据类型与对象的转化
typedefNS_ENUM(NSUInteger,SectionState) {
SectionClose =0,
SectionOpen
};
for(inti =0; i
[sectionStatesaddObject:@(SectionOpen)];
}
NSArray*arr =sectionArr[section];
return[sectionStates[section]integerValue]==SectionOpen? arr.count:0;
19.NSDictionary [selfallValues]&&[self keys]方法注意点——>注意取值时避免越界。
如果字典里只有一对键值对 通过[selfallValues]&&[self keys]方法取key和value时:
NSArray*allValues = [sectionDicallValues][0];
原因:虽然实际有值的元素只有一个。但是allValues是个数组,最后有个nil的元素,这里一定取出第1个元素。
20.用字典进行互斥选择和多选的实现
以下是多选:
字典结构(分区下标:数组(被选中的item对应的URL),分区下标:数组,分区下标:数组,nil)
if(selectDic==nil) {
selectDic= [[NSMutableDictionaryalloc]init];
}
NSString*key = [NSStringstringWithFormat:@"%ld",(long)indexPath.section];
//字典没有数据(value)
if(![selectDicobjectForKey:key]) {
NSArray*sectionValue =sectionArr[indexPath.section];
NSMutableArray*valueArr = [NSMutableArrayarrayWithCapacity:sectionValue.count];
NSDictionary*dic = sectionValue[indexPath.row];
[valueArraddObject:[dicobjectForKey:@"picture"]];
[selectDicsetObject:valueArrforKey:key];
}
//字典有数据(value)
else{
NSArray*resultArray = [selectDicobjectForKey:key];
NSArray*sectionValue =sectionArr[indexPath.section];
NSDictionary*dic = sectionValue[indexPath.row];
NSMutableArray*array = [resultArraymutableCopy];
BOOLisSame =NO;
for(inti =0; i
if([resultArraycontainsObject:[dicobjectForKey:@"picture"]]) {
isSame =YES;
}
}
if(isSame ==YES) {
[arrayremoveObject:[dicobjectForKey:@"picture"]];
}else{
[arrayaddObject:[dicobjectForKey:@"picture"]];
}
[selectDicsetObject:arrayforKey:key];
}
21.字典遍历————>>层层遍历
NSMutableArray*deleteArray = [[NSMutableArrayalloc]init];
NSArray*allValueArray = [selectDicallValues];
NSLog(@"%@",allValueArray);
for(inti =0; i
NSArray*valueArray = [allValueArrayobjectAtIndex:i];
for(intj =0; j
[deleteArrayaddObject:[valueArrayobjectAtIndex:j]];
}
}
if(deleteArray.count==0) {
bottomView.backgroundColor= [UIColorcolorWithRed:248/255.0green:248/255.0blue:248/255.0alpha:0.95];
deleteBTN.enabled=NO;
[deleteBTNsetTitleColor:[UIColorlightGrayColor]forState:UIControlStateNormal];
}else{
bottomView.backgroundColor= [uPublicgetColor:@"#5fcaf8"];
deleteBTN.enabled=YES;
[deleteBTNsetTitleColor:[UIColorwhiteColor]forState:UIControlStateNormal];
}
22.UITableView中自定义cell 分区头 分区尾 表头 表尾———>>控件太多,卡顿的问题
现象:自定义分区头,在拿到数据后使用setter方法 进行 UI数据的渲染。自下而上滑动,刚到分区头,出现卡顿。
原因:自下而上滑动,UITbaleView会再次调用viewForHeader方法,此时,自定义分区头又会调用etter方法 进行 UI数据的渲染,而UI数据的渲染中子控件特别多————>>耗费内存———>>卡顿。(*****PS:UITableView本身滑动就非常耗内存)
方法:自定义分区头,在拿到数据后使用setter方法 进行 UI数据的渲染时————>>开个子线程。
23.[nameisEqualToString:@"上"]和[namerangeOfString:voiceStr].location!=NSNotFound————>>@“”空串
当name是个@“”上面方法恒成立————>>true
解决:比较对象放在前面————————>>>[@"上"isEqualToString:chines]