性能優(yōu)化

一、循環(huán)引用

1.第一種方式 weak+strong(最常用)

- (void)one{
    __weak typeof(self) weakSelf = self;
    self.block = ^{
        __strong typeof(self) strongSelf = weakSelf;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"%@",strongSelf.name); // self - nil name - nil
        });
    };
    
    self.block();
}

2.第二種方式__block

- (void)two{
    __block ViewController *vc = self; // vc 結(jié)構(gòu)體
    self.block = ^{
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"%@",vc.name); // self - nil name - nil
            vc = nil;
        });
    };
    self.block();
}

3.第三種方式 傳參(效率最高)

self.blockVc = ^(ViewController *vc){
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"%@",vc.name); // self - nil name - nil
        });
    };
    self.blockVc(self);

二、強(qiáng)引用

- (void)initTimer {
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self.target selector:@selector(timerSel) userInfo:nil repeats:YES];
}
- (void)timerSel{
    num++;
    NSLog(@"num----> %d",num);
}

因?yàn)閞unloop -> timer -> target -> self 造成了強(qiáng)引用
1.簡陋的解決

-(void)viewWillDisappear:(BOOL)animated {
    [self.timer invalidate];
    self.timer = nil;
}

2.好一點(diǎn)的方式,但是不夠靈活

-(void)didMoveToParentViewController:(UIViewController *)parent{
    if (parent == nil) {
        [self.timer invalidate];
        self.timer = nil;
    }
    NSLog(@"結(jié)束");
}

3.中間層
定義一個(gè)中間層

@interface YHTimerWapper : NSObject
- (instancetype)yh_initWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
- (void)yh_invalidate;
@end
@interface YHTimerWapper()
@property (nonatomic, weak) id target;
@property (nonatomic, assign) SEL aSelector;
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation YHTimerWapper
- (instancetype)yh_initWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo{
    if (self == [super init]) {
        self.target     = aTarget;
        self.aSelector  = aSelector;
        self.timer      = [NSTimer scheduledTimerWithTimeInterval:ti target:self selector:@selector(timerSel) userInfo:userInfo repeats:yesOrNo];
    }
    return self;
}
- (void)timerSel{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    // 讓編譯器出棧偷遗,恢復(fù)狀態(tài),繼續(xù)編譯后續(xù)的代碼兰吟!
    if ([self.target respondsToSelector:self.aSelector]) {
        [self.target performSelector:self.aSelector];
    }
#pragma clang diagnostic pop
}
- (void)yh_invalidate{
    [self.timer invalidate];
    self.timer = nil;
}

使用

- (void)viewDidLoad {
    [super viewDidLoad];
    //中間層(RACKVOWapper)
    // self -> timerWapper(在self的dealloc方法斷開) <-> timer <- runloop
    self.timerWapper = [[YHTimerWapper alloc] yh_initWithTimeInterval:1 target:self selector:@selector(timerSel) userInfo:nil repeats:YES];
}
- (void)dealloc{
    [self.timerWapper lg_invalidate];
}

4.使用block

self.timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
        NSLog(@"num ");
}];
- (void)dealloc{
    [self.timer invalidate];
    self.timer = nil;
}
  1. NSProxy
    是跟NSObject同級(jí)的類觅廓,加載迅速,消息轉(zhuǎn)發(fā)形式更加清晰
@interface YHProxy : NSProxy
+ (instancetype)proxyWithTransformObject:(id)object;
@end
@interface YHProxy()
@property (nonatomic, weak) id object;
@end
@implementation YHProxy
+ (instancetype)proxyWithTransformObject:(id)object{
    YHProxy *proxy = [YHProxy alloc];
    proxy.object = object;
    return proxy;
}
// sel - imp -
// 消息轉(zhuǎn)發(fā) self.object
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel{
    return [self.object methodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation{
    if (self.object) {
        [invocation invokeWithTarget:self.object];
    }
}
@end

使用

self.proxy = [YHProxy proxyWithTransformObject:self];
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self.proxy selector:@selector(timerSel) userInfo:nil repeats:YES];

三服鹅、內(nèi)存泄漏檢查方式

1凳兵、靜態(tài)分析Analyze
2、instrument
3企软、MLeaksFinder(更方便)
4庐扫、dealloc

四、啟動(dòng)時(shí)間

  1. 啟動(dòng)分為2種: 冷啟動(dòng)和熱啟動(dòng)
  2. 啟動(dòng)的時(shí)間分為兩部分:main函數(shù)執(zhí)行之前、main函數(shù)?應(yīng)用啟動(dòng)完成
    啟動(dòng)優(yōu)化建議
    main函數(shù)之前
    減少動(dòng)態(tài)庫形庭、合并一些動(dòng)態(tài)庫
    減少Objc類铅辞、分類的數(shù)量、減少Selector數(shù)量
    main函數(shù)?應(yīng)用啟動(dòng)完成
    耗時(shí)操作碘勉,不要放在finishLaunching方法中

動(dòng)態(tài)庫對(duì)啟動(dòng)時(shí)間的影響測試
iOS Dynamic Framework 對(duì)App啟動(dòng)時(shí)間影響實(shí)測

五巷挥、應(yīng)用瘦身

LinkMap查看文件大小
LSUnusedResources 查看未使用的文件

六、渲染

YYFpsLabel檢查渲染
異步渲染

七验靡、網(wǎng)絡(luò)層

防止多次重復(fù)請(qǐng)求

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末倍宾,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子胜嗓,更是在濱河造成了極大的恐慌高职,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辞州,死亡現(xiàn)場離奇詭異怔锌,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)变过,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門埃元,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人媚狰,你說我怎么就攤上這事岛杀。” “怎么了崭孤?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵类嗤,是天一觀的道長。 經(jīng)常有香客問我辨宠,道長遗锣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任嗤形,我火速辦了婚禮精偿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘派殷。我一直安慰自己还最,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布毡惜。 她就那樣靜靜地躺著拓轻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪经伙。 梳的紋絲不亂的頭發(fā)上扶叉,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天勿锅,我揣著相機(jī)與錄音,去河邊找鬼枣氧。 笑死溢十,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的达吞。 我是一名探鬼主播张弛,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼酪劫!你這毒婦竟也來了吞鸭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤覆糟,失蹤者是張志新(化名)和其女友劉穎刻剥,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體滩字,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡造虏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了麦箍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漓藕。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖挟裂,靈堂內(nèi)的尸體忽然破棺而出撵术,到底是詐尸還是另有隱情,我是刑警寧澤话瞧,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站寝姿,受9級(jí)特大地震影響交排,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜饵筑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一埃篓、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧根资,春花似錦架专、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至裤纹,卻和暖如春委刘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國打工锡移, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留呕童,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓淆珊,卻偏偏與公主長得像夺饲,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子施符,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 目錄一: 卡頓檢測以及原理runloop卡頓檢測消息轉(zhuǎn)發(fā)解決定時(shí)器循環(huán)引用GCD定時(shí)器封裝NSProxy消息轉(zhuǎn)發(fā)T...
    江水東流閱讀 8,964評(píng)論 2 30
  • 為了表示我對(duì)簡書『飽醉豚』事件的不滿往声,簡書不再更新,后續(xù)有文章只更新 個(gè)人博客和 掘金 歡迎移步 個(gè)人博客或者 掘...
    eagleyz閱讀 664評(píng)論 0 4
  • 一操刀、CPU和GPU 的介紹 1.1烁挟、在屏幕成像的過程中,CPU和GPU起著至關(guān)重要的 作用CPU(Central...
    IIronMan閱讀 2,600評(píng)論 1 17
  • 簡述總結(jié):界面優(yōu)化(Cpu5處——Gpu4處)——網(wǎng)絡(luò)優(yōu)化(耗電)——定位優(yōu)化——APP冷啟動(dòng)優(yōu)化——APP內(nèi)存優(yōu)...
    白水灬煮一切閱讀 3,060評(píng)論 0 16
  • 一骨坑、CPU和GPU 的介紹 在屏幕成像的過程中撼嗓,CPU和GPU起著至關(guān)重要的作用 1、CPU(中央處理器) 對(duì)象...
    春風(fēng)依舊閱讀 224評(píng)論 0 2