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.lxweimin.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]