iOS-大小坑

本文大體是一些細節(jié)性的小坑,不定期更新,歡迎糾正。

關(guān)于變量的讀寫


變量的讀寫通常使用 self. 和 _ 兩種方式,但他們有什么區(qū)別呢?我們先看下面兩個例子。

@property (nonatomic, strong) NSMutableString * str1;
@property (nonatomic, copy) NSMutableString * str2;

假設(shè)我們定義了兩個變量,一個用strong屬性修飾,一個用copy屬性修飾。

NSMutableString * strA = [[NSMutableString alloc] initWithString:@"A"];
self.str1 = strA;
self.str2 = strA;
[strA appendFormat:@"C"];
NSLog(@"%@, %@", _str1, _str2); // 輸出AC, A

第一個例子使用了self.來給變量賦值,由于str2使用了copy屬性修飾,因此它給strA創(chuàng)建了一個不可變副本,當strA發(fā)生變化時,不影響str2。

NSMutableString * strB = [[NSMutableString alloc] initWithString:@"B"];
_str1 = strB;
_str2 = strB;
[strB appendFormat:@"C"];
NSLog(@"%@, %@", _str1, _str2); // 輸出BC, BC

第二個例子直接使用來賦值,但是輸出的結(jié)果卻與第一個不一致,str2也發(fā)生了改變。
當我們使用self.方式時,實際上是調(diào)用了set方法來對變量賦值,而使用
賦值時繞過了set方法,因此copy修飾符沒生效,采用了默認的strong修飾符,所以str2的值也跟著發(fā)生改變。改進方法:

_str2 = [strB copy];

關(guān)于常量的定義


常量我們通常使用#define或者extern來定義。
define其實就是個替代宏,編譯器在編譯的時候會把該位置轉(zhuǎn)為具體的代碼,如果使用define來定義常量,并且該常量被應(yīng)用于多個位置,那么就可能造成內(nèi)存的浪費。舉一個簡單的例子:

#define NAME @"name"

NSString * name1 = [NSString stringWithString:NAME];
NSString * name2 = [NSString stringWithString:NAME];
// 上面兩行代碼在編譯的時候就相當于下面這種寫法,多開辟了兩個name的內(nèi)存空間
NSString * name1 = [NSString stringWithString:@"name"];
NSString * name2 = [NSString stringWithString:@"name"];

因此比較合理的做法是采用extern的方式來聲明。

// 頭文件(.h)中定義
extern NSString * const name;
// 實現(xiàn)文件(.m),在import下方書寫
NSString * const name = @"name";

這種方式的寫法在未使用name這個常量時,它是個nil值不占內(nèi)存空間。當?shù)谝淮问褂胣ame時,系統(tǒng)自動為其分配內(nèi)存,并持續(xù)存在,后面的第N次使用都相當于訪問這塊內(nèi)存。
另外const的位置也是有講究的,舉個例子:

NSString * const constVal1 = @"A";
NSString const * constVal2 = @"B";
const NSString * constVal3 = @"C";

constVal1 = @"A1"; // 報錯
constVal2 = @"B1";
constVal3 = @"C1";

constVal1就是我們常規(guī)意義上的常量,它的值是無法改變的。而對于constVal2和constVal3它倆是沒有區(qū)別的,都是代表指針地址不變,但可指向新的值。
</br></br>

iOS7的手勢返回


這里說的手勢返回并不是指深度定制的返回動畫,而是自帶的從屏幕邊緣滑動返回。
重新設(shè)定導航欄的leftBarButtonItem后會導致手勢返回失效,此時可以通過一行簡單的代碼來使其重新生效:

self.navigationController.interactivePopGestureRecognizer.delegate
 = (id)self;

但我們的項目通常會給VC設(shè)定一個公共的父類,在父類中設(shè)置公共樣式的leftBarButtonItem,并且把這行代碼寫在viewDidLoad中。此時會遇到一個問題——在第一個VC中觸發(fā)邊緣手勢,然后點擊任意可跳轉(zhuǎn)入二級VC的按鈕,會發(fā)現(xiàn)界面假死了。
最大的原因就在于把上述代碼寫在父類的viewDidLoad時,由于第一個VC也繼承了該父類,因此也會觸發(fā)邊緣返回手勢,但因為已經(jīng)是棧底了無法返回,就會導致返回出錯,導致想要進入二級界面時,界面假死。
一個合理的解決方案是將其寫在viewDidAppear中,并且過濾第一個VC:


- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if([self.navigationController.viewControllers count] >= 2) {
        self.navigationController.interactivePopGestureRecognizer.enabled = YES;
        self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;
    }else{
        self.navigationController.interactivePopGestureRecognizer.delegate = nil;
        self.navigationController.interactivePopGestureRecognizer.enabled = NO;
    }
}

狀態(tài)欄

在iOS7之后控制狀態(tài)欄的樣式通常使用-preferredStatusBarStyle方法來設(shè)定狀態(tài)欄的風格。(注:View controller-based status bar appearance 要設(shè)定為 YES)
但有時候你會發(fā)現(xiàn),在導航控制器里面的VC重寫此方法是無效的。原因很簡單,主控權(quán)不在當前VC中,而是在它的父VC——NavigationController中。有兩種解決方式,重寫NavC中的-preferredStatusBarStyle方法或-childViewControllerForStatusBarStyle方法。

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return [self.topViewController preferredStatusBarStyle];
}
// 上下兩種方法任選一
- (UIViewController *)childViewControllerForStatusBarStyle
{
    return self.topViewController;
}

另外,狀態(tài)欄的隱藏是可以帶動畫,一種是Fade,一種是Slide

- (BOOL)prefersStatusBarHidden
{
    return ![UIApplication sharedApplication].statusBarHidden;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation
{
    return UIStatusBarAnimationSlide;
}
- (IBAction)hideOrShowStatusBar:(id)sender {
    [UIView animateWithDuration:0.2 animations:^{
        [self setNeedsStatusBarAppearanceUpdate];
    }];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

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

  • java筆記第一天 == 和 equals ==比較的比較的是兩個變量的值是否相等,對于引用型變量表示的是兩個變量...
    jmychou閱讀 1,515評論 0 3
  • 1 在《人民的名義》中有這樣一個片段:李達康書記親自到信訪局考察,讓孫連成趴著匯報。 原因是李達康通過他家的保姆知...
    yiersansiwuliu閱讀 770評論 0 2
  • 銀天未見春來雨,雨水卻遇雪冬寒。 寒夜不知花開早,早來忽現(xiàn)一樹銀! (后兩句是巍巍的,改了一個【早】字。)
    Oak水木閱讀 177評論 0 0
  • 在我為數(shù)不多的面試,尤其職能類崗位面試的過程中,見過一些畢業(yè)不久、資歷尚淺的面試者,他們暫未形成自己看待事物的一套...
    無聊小事閱讀 413評論 0 1
  • 引言:秋千,相信每一個人都玩過,而且她又是常常在中國的詩詞歌賦里被提及,尤其是在女子傷春感懷的文章里。作為最富文學...
    羅克閱讀 1,897評論 0 0