1,UIImage *image = [UIImage imageNamed:tempString];
這樣看是圖片記憶體會爆炸而且不會釋放,圖片多了出大事,圖片少的并且重用多可以用性能會很高
NSString *path = [[NSBundle mainBundle] pathForResource:tempString
ofType:@“jpeg”];
UIImage *image = [UIImage imageWithContentsOfFile:path];
2.很多圖片 先加到boundle里面性能好一點
mNzZG4ubmV0L2pva2VyNG8=,size_16,color_FFFFFF,t_70)
3,計時器實作
-(void)downSecondHandle:(NSString )aTimeString{
NSDateFormatter dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@“yyyy-MM-dd HH:mm:ss”];
NSDate endDate = [dateFormatter dateFromString:[self timeWithTimeIntervalString:aTimeString]]; //將秒數轉化成時間得到的結束時間
//initwith將時間初始化為00,1,1+,timeIntervalSinceReferenceDate回傳與00,1,1的秒數間隔
//NSDate endDate_tomorrow = [[NSDate alloc] initWithTimeIntervalSinceReferenceDate:([endDate timeIntervalSinceReferenceDate])];
NSDate startDate = [NSDate date];
NSString dateString = [dateFormatter stringFromDate:startDate];
NSLog(@“現在的時間 %@”,dateString);
//STimeInterval timeInterval =[endDate_tomorrow timeIntervalSinceDate: startDate];
NSTimeInterval timeInterval =[endDate timeIntervalSinceDate: startDate];
if (_timer==nil) {
//得到參考地址以方便修改資料
__block int timeout = timeInterval; //倒計時時間
if (timeout!=0) {
//GCD中的佇列稱為dispatchqueue,它可以保證先進來的任務先得到執行通過它能夠大大簡化多執行緒編程,工程師只要將要執行的任務(執行代碼塊)放入佇列中,GCD將會為需要執行的任務創建thread,從而放入dispatch queue中,當將任務添加到佇列立即安排開始執行,
dispatch_queue_t queue =
//dispatch_async函式會將傳入的block塊放入指定的queue里運行,這個函式是異步的,這就意味著它會立即回傳而不管block是否運行結束,因此,我們可以在block里運行各種耗時的操作(如網路請求) 而同時不會阻塞UI執行緒,
//dispatch_get_global_queue 會獲取一個全域佇列,我們姑且理解為系統為我們開啟的一些全域執行緒,我們用priority指定佇列的優先級,而flag作為保留欄位備用(一般為0),
//dispatch_get_main_queue會回傳主佇列,也就是UI佇列,它一般用于在其它佇列中異步完成了一些作業后,需要在UI佇列中更新界面(比如上面代碼中的[selfupdateUIWithResult:result])的情況,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//datapatch_source create 實作定時器
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
//設定引數
dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0NSEC_PER_SEC, 0); //每秒執行
dispatch_source_set_event_handler(_timer, ^{
if(timeout<=0){ //倒計時結束,關閉
dispatch_source_cancel(_timer);
_timer = nil;
dispatch_async(dispatch_get_main_queue(), ^{
self.dayLabel.text = @"";
self.hourLabel.text = @“00”;
self.minueLabel.text = @“00”;
self.secondLabel.text = @“00”;
});
}else{
NSLog(@“正在更新時間”);
int days = (int)(timeout/(360024));
if (days==0) {
self.dayLabel.text = @"";
}
int hours = (int)((timeout-days243600)/3600);
int minute = (int)(timeout-days243600-hours3600)/60;
int second = timeout-days243600-hours3600-minute*60;
dispatch_async(dispatch_get_main_queue(), ^{
if (days==0) {
self.dayLabel.text = @“0”;
}else{
self.dayLabel.text = [NSString stringWithFormat:@"%d",days];
}
if (hours<10) {
self.hourLabel.text = [NSString stringWithFormat:@“0%d”,hours];
}else{
self.hourLabel.text = [NSString stringWithFormat:@"%d",hours];
}
if (minute<10) {
self.minueLabel.text = [NSString stringWithFormat:@“0%d”,minute];
}else{
self.minueLabel.text = [NSString stringWithFormat:@"%d",minute];
}
if (second<10) {
self.secondLabel.text = [NSString stringWithFormat:@“0%d”,second];
}else{
self.secondLabel.text = [NSString stringWithFormat:@"%d",second];
}
});
timeout–;
}
});
//再次恢復計數
dispatch_resume(_timer);
}
}
}
4, 圖片漸變可以用CAGradientLayer,設定從whiteColor到clearColor的漸變從而達到圖片漸變
5,nil是表示0x0,可以理解為空指標,release是釋放記憶體,
例如:你開辟了一塊記憶體p= [[nsobject alloc] init]; 這個時候p是指向這塊記憶體區域的,如果你直接p=nil,會造成這塊記憶體沒有被釋放,記憶體泄露, 如果[p release]釋放了記憶體,但是p還是指向這個記憶體地址,如果在操作p會出現EXC_BAD_ACCESS,正確的做法應該是釋放后,把p指向nil
nil、Nil、NULL的區別
nil:指向oc中物件的空指標,針對物件,
Nil:指向oc中類的空指標,針對類,
NULL:指向其他型別的空指標,如一個c型別的記憶體指標,基本資料型別為空,基本型別,
NSNull:在集合物件中,表示空值的物件,
若obj為nil
[obj message]將回傳NO,而不是NSException
若obj為NSNull
[obj message]將拋出例外NSException
6,tabview重繪資料紊亂;tabview會重用cell,而cell是當一個cell消失在螢屏外就會被回收,當回到螢屏就會重新去chon如果你采用了static NSString* cellID = @“cellID”;這樣的方式定義cell,
7,property方法系統自動生成了set與get方法,而且會以_下劃線的形式把資料存到地址里面,所以只要有一個人修改了地址里面的值,其他的都會知道,
8,xcode12,如果有網路圖片,或者網路資料加載不了報錯,安全配置什么的,其實不需要,只要把資料的URL 把http變成https就行了,這樣就不會阻攔了
9,__block就是拿到變數真實地址,在block中操作就可以直接更改變數的值,不然拿到的就是瞬時值
10 橫屏優先級的問題,general == appDelegate >> rootViewController >> nomalViewController,高級的開了不能旋轉,低級的怎么開都沒有用
可能造成tableView卡頓的原因有:
1.最常用的就是cell的重用, 注冊重用識別符號
如果不重用cell時,每當一個cell顯示到螢屏上時,就會重新創建一個新的cell
如果有很多資料的時候,就會堆積很多cell,
如果重用cell,為cell創建一個ID,每當需要顯示cell 的時候,都會先去緩沖池中尋找可回圈利用的cell,如果沒有再重新創建cell
2.避免cell的重新布局
cell的布局填充等操作 比較耗時,一般創建時就布局好
如可以將cell單獨放到一個自定義類,初始化時就布局好
3.提前計算并快取cell的屬性及內容
當我們創建cell的資料源方法時,編譯器并不是先創建cell 再定cell的高度
而是先根據內容一次確定每一個cell的高度,高度確定后,再創建要顯示的cell,滾動時,每當cell進入憑虛都會計算高度,提前估算高度告訴編譯器,編譯器知道高度后,緊接著就會創建cell,這時再呼叫高度的具體計算方法,這樣可以方式浪費時間去計算顯示以外的cell
4.減少cell中控制元件的數量
盡量使cell得布局大致相同,不同風格的cell可以使用不用的重用識別符號,初始化時添加控制元件,
不適用的可以先隱藏
5.不要使用ClearColor,無背景色,透明度也不要設定為0
渲染耗時比較長
6.使用區域更新
如果只是更新某組的話,使用reloadSection進行區域更
7.加載網路資料,下載圖片,使用異步加載,并快取
8.少使用addView 給cell動態添加view
9.按需加載cell,cell滾動很快時,只加載范圍內的cell
10.不要實作無用的代理方法,tableView只遵守兩個協議
11.快取行高:estimatedHeightForRow不能和HeightForRow里面的layoutIfNeed同時存在,這兩者同時存在才會出現“竄動”的bug,所以我的建議是:只要是固定行高就寫預估行高來減少行高呼叫次數提升性能,如果是動態行高就不要寫預估方法了,用一個行高的快取字典來減少代碼的呼叫次數即可
12.不要做多余的繪制作業,在實作drawRect:的時候,它的rect引數就是需要繪制的區域,這個區域之外的不需要進行繪制,例如上例中,就可以用CGRectIntersectsRect、CGRectIntersection或CGRectContainsRect判斷是否需要繪制image和text,然后再呼叫繪制方法,
13.預渲染影像,當新的影像出現時,仍然會有短暫的停頓現象,解決的辦法就是在bitmap context里先將其畫一遍,匯出成UIImage物件,然后再繪制到螢屏;
14.使用正確的資料結構來存盤資料,
15 可變陣列與NSStringcopy深淺
copy對NSArray進行的是淺拷貝,
mutableCopy對NSArray進行的是深拷貝,且拷貝之后陣列變成了一個可變陣列,
copy對NSMutableArray進行的是深拷貝,拷貝之后的新陣列是一個不可變陣列,
mutableCopy對NSMutableArray進行的是深拷貝,且拷貝之后是一個新的可變陣列,
靜態字串,無論是使用strong還是copy修飾,字串之間的修改的都是獨立的,不會互相影響,
strong修飾的self.firstName兩次的列印值是不一樣的,第二次列印值和orgMstr是一樣的,對orgMstr的修改,竟然影響了self.firstName的值,產生了我們不想要的結果(意外值串改),這在開發中會導致預想不到的bug,排查困難,
而使用copy修飾的self.secondName兩次的列印值是一樣的,就是說orgMStr和self.secondName的修改是獨立的,不會互相影響,這才是開發真正需要的效果,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/286623.html
標籤:其他
