iOS開發中 new與alloc/init的區別 及 [NSArray array] 和 [[NSArray alloc]init] 及 self. 和 _ 的區別
專案過程中,想到這幾個概念的區別有些模糊,於是縱觀各種資料,來篇博文為自己記錄下,也為小夥伴們說說我的理解。
[className new]
和 [[className alloc] init]
的區別
1.在實際開發中很少會用到new,一般建立物件咱們看到的全是[[className alloc] init]
但是並不意味著你不會接觸到new,在一些程式碼中還是會看到[[className alloc] init],
還有去面試的時候,也很可能被問到這個問題。
2.那麼,他們兩者之間到底有什麼區別呢
我們看原始碼:
- + new
- {
- id newObject = (*_alloc)((Class)self, 0);
- Class metaClass = self->isa;
- if (class_getVersion(metaClass) > 1)
- return [newObject init];
- else
- return newObject;
- }
- //而 alloc/init 像這樣:
- + alloc
- {
- return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());
- }
- - init
- {
- return self;
- }
通過原始碼中我們發現,[className new]基本等同於[[className alloc] init];
區別只在於alloc分配記憶體的時候使用了zone.
這個zone是個什麼東東呢?
它是給物件分配記憶體的時候,把關聯的物件分配到一個相鄰的記憶體區域內,以便於呼叫時消耗很少的代價,提升了程式處理速度;
3.而為什麼不推薦使用new?
不知大家發現了沒有:如果使用new的話,初始化方法被固定死只能呼叫init.
而你想呼叫initXXX怎麼辦?沒門兒!據說最初的設計是完全借鑑Smalltalk語法來的。
傳說那個時候已經有allocFromZone:這個方法,
但是這個方法需要傳個引數id myCompanion = [[TheClass allocFromZone:[self zone]] init];
這個方法像下面這樣:
- + allocFromZone:(
- {
- return (*_zoneAlloc)((Class)self, 0, z);
- }
- //後來簡化為下面這個:
- + alloc
- {
- return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());
- }
但是,出現個問題:這個方法只是給物件分配了記憶體,並沒有初始化例項變數。
是不是又回到new那樣的處理方式:在方法內部隱式呼叫init方法呢?
後來發現“顯示呼叫總比隱式呼叫要好”,所以後來就把兩個方法分開了。
概括來說,new和alloc/init在功能上幾乎是一致的,分配記憶體並完成初始化。
差別在於,採用new的方式只能採用預設的init方法完成初始化,
採用alloc的方式可以用其他定製的初始化方法。
再來說一個突然想起來的問題:[NSArray array] 和 [[NSArray alloc]init] (包括字典等同類) 的使用方法的區別:
alloc (記憶體分配)以及init(初始化) Objective-C 協議分為非正式協議和正式協議 .
這兩個方式都是建立一個空的Array
[NSArray array]不需要release,使用autoreleasepool機制。
[[NSArray alloc] init]需要自己手動release
專案使用崩潰例項:
在ViewDidLoad中
jsonDataDic = [NSMutableDictionary dictionary];
[self jsonParse];
建立一個空字典,在jsonParse中使用了這個詞典,導致程式崩潰
解決方法:在jsonDataDic前面加上self.即可
原因:不加的話,指標的作用域僅在ViewDidLoad中,進入jsonParse後該指標已釋放,成為了一個野指標,再對其進行操作,使程式崩潰。
注意:字典是沒有順序的,字典的allkeys或者allvalues存放到陣列中是隨機的。
總結:
new做的事情和alloc init是一樣的,當然你要構造方法是init的時候完全可以用new來代替 ,alloc 不僅僅可以使用init構造方法,更可以自定義構造方法e.g initWithFrame等等。
另外,alloc開闢空間後能夠自動清空新開闢記憶體空間中的老資料,不會出現莫名奇妙的錯誤,見《Objective-C基礎教程》
說到這個問題,可能有小夥伴又懵了,那self.和 _有什麼區別呢,再說下這兩個 :
( - -!沒完了)
self.programStack等於[self programStack],會走你的懶載入方法;而_programStack類似於self->_programStack。
用self點出屬性是更好的選擇,因為這樣可以相容懶載入,同時也避免了使用下劃線的時候忽視了self這個指標,後者容易在block中造成迴圈引用。
科普:懶載入(Load On Demand)是一種獨特而又強大的資料獲取方法,它能夠在使用者滾動頁面的時候自動獲取更多的資料,而新得到的資料不會影響原有資料的顯示,同時最大程度上減少伺服器端的資源耗用。
這兩種使用方式顯然是不一樣的。
主要是涉及到記憶體管理的問題。self.propertyName 使用self. 是對屬性的訪問。使用_ 是對區域性變數的訪問。
所有被宣告為屬性的成員,在ios5 之前需要使用編譯器指令@synthesize 來告訴編譯器幫助生成屬性的getter,setter方法。之後這個指令可以不用人為指定了,預設情況下編譯器會幫我們生成。 編譯器在生成getter,setter方法時是有優先順序的,它首先查詢當前的類中使用者是否已定義屬性的getter,setter方法,如果有,則編譯器會跳過,不會再生成,使用使用者定義的方法。 也就是說你在使用self.propertyName 時是在呼叫一個方法。
_______________________________________________________哥哥愛開發_________________________________________________________________
本篇博文有查詢資料中大神的理論引用,有自己的原創理解,只為整理在一起方便理解。
最後:開發,只為簡單生活,技術改變世界!~yeah~
相關推薦
iOS開發中 new與alloc/init的區別 及 [NSArray array] 和 [[NSArray alloc]init] 及 self. 和 _ 的區別
專案過程中,想到這幾個概念的區別有些模糊,於是縱觀各種資料,來篇博文為自己記錄下,也為小夥伴們說說我的理解。 [className new] 和 [[className alloc] init] 的區別 1.在實際開發中很少會用到new,一般建立物件咱們看到的全
iOS開發中地圖與定位
視圖 編寫 aps 簡單 -a 第三方 span spa margin 不管是QQ還是微信的移動client都少不了定位功能,之前在微信demo中沒有加入定位功能,今天就寫個定位的小demo來了解一下定位和地圖的東西。地圖和定位看上去是挺高大上一東西。其有使用方法比
iOS 開發中null 與的處理
原文連結:http://www.jianshu.com/p/a73aab1c1422 針對(null)這種情況,將一個字串賦值為nil,列印輸出結果就是(null)那麼湧入下來做判斷if(result==nil) { NSLog(@"執行"); } 針對<null>的情況 f([r
iOS 開發中OC 與 JS的互動
iOS原生應用和web頁面的互動有iOS7之後的JavaScriptCore、攔截協議、第三方框架WebViewJavaScriptBridge、iOS8之後的WKWebView幾種方法,這一章我們主要講解JavaScriptCore和攔截協議這兩種辦法。WebViewJ
iOS開發知識之:iOS開發中alloc和new的區別
1.在實際開發中很少會用到new,一般建立物件咱們看到的全是[[className alloc] init] 但是並不意味著你不會接觸到new,在一些程式碼中還是會看到[className new], 還有去面試的時候,也很可能被問到這個問題。 2.那麼,他們兩者之間到底有什麼區別呢 我們看原始碼:
ios開發中類方法與例項方法區別 以及self有什麼不同
Objective-C裡面既有例項方法也類方法。類方法(Class Method) 有時被稱為工廠方法(Factory Method)或者方便方法(Convenience method)。工廠方法的稱謂明顯和一般意義上的工廠方法不同,從本質上來說,類方法可以獨立於物件而執行,所以在其他的語言裡面類方法有的
IOS開發之——objectForKey與valueForKey在NSDictionary中的差異
什麽 iat app 報錯信息 lease 方法 去掉 defined atom 從 NSDictionary 取值的時候有兩個方法,objectForKey: 和 valueForKey:,這兩個方法具體有什麽不同呢? 先從 NSDictionary 文檔中來看這兩個方法
iOS開發中的position+anchorPoint與frame應用解釋
移動 pos 限制 一起 frame -1 必須 posit 解釋 我剛開始時非常困惑這兩個地方, 所以現在好好解釋一下他們的聯系. 1/ position與anchorPoint是一對屬性, 經常一起設置來確定控件的位置 frame單獨設置 2/ position
iOS開發之OC與swift開發混編教程,代理的相互呼叫,block的實現。OC呼叫Swift中的代理, OC呼叫Swift中的Block 閉包
本文章將從兩個方向分別介紹 OC 與 swift 混編 1. 第一個方向從 swift工程 中引入 oc類 1. 1 如何在swift的類中使用oc類 1.2 如何在swift中實現oc的代理方法 &
敏捷開發之Scrum掃盲,及敏捷開發中XP與SCRUM的區別
現在敏捷開發是越來越火了,人人都在談敏捷,人人都在學習Scrum和XP... 為了不落後他人,於是我也開始學習Scrum,今天主要是對我最近閱讀的相關資料,根據自己的理解,用自己的話來講述Scrum中的各個環節,主要目的有兩個,一個是進行知識的總結,另外一個是覺得網上很多學習資料的講述方式讓初學者不太容易
移動端開發在iOS系統中 new Date() 返回 NaN 的問題
問題: 通過 new Date() 函式將後臺返回的時間('2021-11-25')獲取時間戳。在 chrome 瀏覽器中沒有出現問題,但在 iPhone 真機測試的時候,顯示的結果不符合預期。通過除錯發現 iOS 中 new Date('2021-11-25') 返回的結果是 NaN,問題出現的原因是
iOS開發中Block的理解與使用
// 隨機生成的顏色 UIColor *color = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:1]; // 第二步 給Blo
iOS開發中各種關鍵字的區別
1.一些概念 1.淺Copy:指標的複製,只是多了一個指向這塊記憶體的指標,共用一塊記憶體。 深Copy:記憶體的複製,兩塊記憶體是完全不同的, 也就是兩個物件指標分別指向不同的記憶體,互不干涉。 2.atomic是Objc使用的一種執行緒保護技術, 基本上來講
Android開發中佈局與元件(二)—— padding 與 margin 的區別
在 Android開發中我們會設定某個檢視相對於別的檢視的距離,這時我們就要用到 margin 和 padding ,但是有時候很容易把這兩個屬性弄混淆,那我們就看看他們的區別。 外邊距(margin): 屬於佈局引數,決定兩個元件之間的距離。作用於多個元件之間。 內邊距(
iOS開發之OC與swift開發混編教程,代理的相互呼叫,block的實現。OC呼叫Swift中的代理, OC呼叫Swift中的Block 閉包,swift 3.0
最新一些學妹問起,所以抽點時間來寫的,適合入門級別的swift 與 OC 混編 的程式猿。 本文章將從兩個方向分別介紹 OC 與 swift 混編 1. 第一個方向從 swift工程 中引入 oc類 1. 1 如何在swift的類中使用oc類 1
iOS開發中(null)與的處理
補充一個知識 NULL nil Nil NSNull的去唄 標識 值 含義 NULL (void *)0 C指標的字面零值 nil
iOS開發中同時識別旋轉與縮放手勢
今天我在使用UIRotationGestureRecognizer和UIPinchGestureRecognizer時,發現它們在預設情況下不能同時被識別。而且在真機操作時,經常發生只識別縮放,難以識別旋轉的情況。所以將它們設為能同時識別是非常有必要的。 經過
iOS開發之swift與OC混編出現的坑,oc中不能對swift的代理進行呼叫,不能訪問swift中的代理,swift中的回撥方法
1. swift與oc混編譯具體怎麼實現,這兒我就不重複講出了,網上有大把的人講解。 2. 在swift與OC混編的編譯環境下, oc類不能訪問swift建立類中的代理? 解決方法如下: 在代理的頭部加上 @objc(代理名字),這樣就在外部就可以訪問了,如下圖。 然
iOS開發時OC與C的混編中,strcpy導致的記憶體溢位、野指標
在最近的專案開發中,由於需要使用C語言的演算法供給OC專案呼叫,所以研究了一下OC與C的混編及.a庫的相關生成。而在混編的過程中,C語言的演算法都能正常呼叫了,但是被一個問題困擾了很長一段時間,就是在
兩張圖看懂Android開發中MVC與MVP的區別
看了很多文章,沒有很好的文章能簡明扼要的說清楚Android開發中MVC和MVP的區別。MVC很早就出來了,之前廣泛用於JavaWeb開發中,MVC也可以用來開發Android,但是有些水土不服! 1、MVC結構示意圖 2、MVP結構示意圖