1.xcode5和xcode7區(qū)別
- 1.xcode7沒有Frameworks文件夾,xcode7內部會自動幫你導入一些常見的框架.
- 2.xcode7多了LaunchScreen.xib,LaunchScreen.xib設置啟動界面,而且可以確定模擬器或者真機的真實尺寸,如果沒有設置,默認4s的尺寸(320,480)
- 3.xcode7沒有pch文件
- 4.xcode5當中也有info.plist,只不過它的名字很長.是工程的名稱.
2.pch文件原理
- 會把pch里面的所有內容導入到每個文件中去
3.UIApplication常見功能
- 1.設置應用提醒數字
- 2.設置連網狀態(tài)
- 3.設置狀態(tài)欄
- 4.跳轉網頁
4.程序完整啟動流程
- 1.執(zhí)行Main
- 2.執(zhí)行UIApplicationMain函數.
- 3.創(chuàng)建UIApplication對象,并設置UIApplicationMain對象的代理.
UIApplication的第三個參數就是UIApplication的名稱,如果指定為nil,它會默認為UIApplication.
UIApplication的第四個參數為UIApplication的代理. - 4.開啟一個主運行循環(huán).保證應用程序不退出.
- 5.加載info.plist.加載配置文件.判斷一下info.plist文件當中有沒有Main storyboard file base name
里面有沒有指定storyboard文件,如果有就去加載info.plist文件,如果沒有,那么應用程序加載完畢.
5.UIWindow是什么?
- UIWindow是一種特殊的UIView,通常在一個app中至少有一個UIWindow
- iOS程序啟動完畢后掷酗,創(chuàng)建的第一個視圖控件就是UIWindow,接著創(chuàng)建控制器的view浅役,
- 最后將控制器的view添加到UIWindow上,于是控制器的view就顯示在屏幕上了
- 一個iOS程序之所以能顯示到屏幕上廓鞠,完全是因為它有UIWindow
6.手動創(chuàng)建窗口的步驟
- 1.創(chuàng)建窗口,要有窗口顯示,必須要有強引用.窗口也是控件,要想展示出來.必須得要有尺寸.
- 2.創(chuàng)建控制器
- 3.設置控制器為窗口的根控制器
- 4.顯示窗口
7.makeKeyAndVisable做了哪些事情口四?
- 1.讓窗口成為顯示狀態(tài).
- 2.把根控制器的View添加到窗口上面.
- 3.把當前窗口設置成應用程序的主窗口
8.如何從storyboard中加載控制器魁瞪?
- 1.加載指定的storyBoard
- 2.加載箭頭所指向的控制器.
- 3.加載指定標識的控制器.
9.initWithNibName的加載過程穆律?
- 1.如果沒有指定名稱.指定為nil,那么它就會去先加載跟它相同名稱的Xib.
- 2.如果沒有跟它相同名稱的Xib,那么它就會再去加載跟它相同名稱去點Controller的名字的Xib.
- 3.控制器的init方法會調用initWithNibName:方法.
10.LoadView作用以及LoadView的注意點?
- 控制器調用loadView方法創(chuàng)建控制器的view.
它的默認做法是:- 1.先去判斷當前控制器是不是從StoryBoard當中加載的,如果是,那么它就會從StoryBoard當中加載控制器的View.
- 2.如果不是從StoryBoard當中加載的, 那么它還會判斷是不是從Xib當中創(chuàng)建的控制器.
如果是,那么它就會從xib加載控制器的View. - 3.如果也不是從Xib加載的控制器.那么它就會創(chuàng)建一個空的UIView.設為當前控制器的View.
- 注意點:
- 1.一旦重寫了loadView,表示需要自己創(chuàng)建控制器的View.
- 2.如果控制器的View還沒有賦值,就不能調用控制器View的get方法.會造成死循環(huán).
- 因為控制器View的get方法底層會調用loadView方法
11.UIPickerView是什么控件导俘?基本用法是怎樣的峦耘?
- UIPickerView是選擇控件,用來供用戶選擇一些城市等旅薄,他的基本用法與tableView基本相似辅髓,需要設置數據源和代理,讓其展示數據
12.KVC底層實現(xiàn)少梁?
- 拿字符串與當前類的屬性進行匹配洛口,如果匹配到,就給該屬性賦值
- [item setValue:forKeyPath:key]
- 1.會找有沒有跟key值相同名稱的set方法凯沪,就會調用set方法第焰,把obj傳入
- 2.如果說沒有set方法,那么它會去找有沒有相同名稱妨马,并且?guī)в邢聞澗€的成員屬性挺举,如果有就會給該屬性賦值
- 3.如果也沒有帶下劃線的成員屬性而叼,就看有沒有跟它相同名稱的成員屬性,如果有就會給該屬性賦值
- 4.如果還沒有跟它相同名稱的成員屬性豹悬,就會調用setVale:forUndefineKey:
- 5.如果沒有實現(xiàn)setValue:forUndefinedKey:就會直接報錯
13.導航控制器的view的結構是怎樣的?
- 導航條,導航條的高度為44液荸,y為20
- 專門存放棧頂控制器view的view
14.導航控制器push做了哪些事情?
- 當調用push方法的時候瞻佛,會把要push的控制器從棧里面移除
- 把之前導航控制器中棧頂控制器的view給移除,把當前棧頂控制器的view添加上去
15.導航控制器pop做了哪些事情娇钱?
- 當調用pop方法時, 會把要pop的控制器從棧里移除
- 把之前導航控制器中棧頂控制器View給移除,把當前棧頂控制器添加上去.
- popViewController:把當前控制器從棧中移除
- popToRootViewControllerAnimated:把除了根控制器以外的控制器伤柄,全部從棧中移除
- popToViewController:要返回的控制器必須要在導航控制器的子控制器當中
16.如何設置導航條的內容?
- 導航條的內容由導航控制器的棧頂控制器的navigationItem決定
- 設置標題:.title
- 設置標題視圖:.titleView
- 設置左側樣式:.leftBarButtonItem
- 自定義view:initWithCustomView
- 設置圖片:initWithImage:
17.導航控制器pop操作有哪些文搂?
- 返回到上一級
- 返回到根控制器
- 返回到指定的控制器
18.文本框如何攔截用戶輸入适刀?
- 給指定的文本框,設置代理煤蹭,遵守協(xié)議笔喉,實現(xiàn)代理方法,包括是否允許開始編輯硝皂,是否允許結束編輯常挚,是否允許改變字符等。
19.如何自定義鍵盤稽物?
- 繼承自系統(tǒng)的UITextField,自定義一個鍵盤奄毡,設置文本框的inputView屬性,把鍵盤定義成自己想要的view
20.導航控制器的作用贝或?
- 導航控制器可以通過push/pop操作吼过,實現(xiàn)控制器之間的跳轉
21.如何通過storyboard進行控制器之間的跳轉?
- 在storyBoard當中,選中一個視圖, 按住Ctrol,拖一根線到指定的控制器咪奖,就可以跳轉到指定的控制器
22.控制器view的生命周期
- loadView:加載view的時候調用
- viewDidLoad:當控制器View加載完畢時調用
- viewWillAppear:當控制器View即將顯示時調用
- viewWillLayoutSubviews:當控制器View即將布局子控件時調用
- viewDidLayoutSubviews:當控制器View布局子控件完畢時調用
- viewDidAppear:當控制器View顯示完畢時調用
- viewWillDisappear:當控制器View既將消失時調用
- viewDidDisappear:當控制器View消失完畢時調用
- viewDidUnload:當控制器View卸載的時候調用
23.segue自動跳轉和手動跳轉有什么區(qū)別盗忱?
- 自動跳轉是通過控件拖到下一個控制器.只要一點擊該控件,就會跳轉,
- 一般跳轉之不需要做任何事時, 用此跳轉方法
- 手動跳轉是通過控制器拖線的方式,跳轉到下一個控制器.要給segue綁定標識
- 需要手動執(zhí)行方法才能跳轉.
24.UIAlertController使用步驟
- 第一步:創(chuàng)建控制器:UIAlertController
- 第二步:創(chuàng)建按鈕:UIAlertAction
- 第三步:添加按鈕:[alertVC addAction:action];
- 第四步:顯示彈框.(相當于show操作)presentViewController:alertVC
25.數據順傳的步驟
- 1.要在數據接收控制器當中定義屬性
- 2.獲取數據接收控制器
- 3.給對應的屬性進行賦值.
26.代理傳遞的過程
- 當一個對象發(fā)生某一件事時,想要把自己的東西傳給別人.或是通知別人做某事使用代理.
- 使用場景 上下級之間,通常是它的上一級成為它的代理.
1.定義協(xié)議,在協(xié)議方法中,把要傳的數據,寫成參數
2.定義代理屬性
3.調用代理方法
4.設置代理
5.遵守協(xié)議
6.實現(xiàn)協(xié)議方法.
27.如何取消tableView多余的線
- tableView的footView為一個空白的View.
28.在跳轉之前會執(zhí)行什么方法?
- prepareForSegue方法
在執(zhí)行segue跳轉之前會調用,(不論是自動型跳轉, 還是手動跳轉都會來到這個方法)
29.performSegueWithIdentifier:做了哪些事情?
- 1.會根據標識到Storyboard當中查找有沒有這個標識的segue
- 2.如果有的話,就會創(chuàng)建一個UIStoryboardSegue對象,
- 3.把當前的控制器賦值給UIStoryboardSegue對象sourceViewController segue.sourceViewController = self
- 4.創(chuàng)建UIStoryboardSegue箭頭指向的控制器.創(chuàng)建完畢后.把創(chuàng)建的控制器給UIStoryboardSegue對象destinationViewController賦值
- 5.調用當前控制器的prepareForSegue方法,告訴你線的準備工作已經完成.問你有沒有要傳遞數據給目標控制器.
- 6.等prepareForSegue執(zhí)行完畢后,才去做真正的跳轉 UIStoryboardSegue對象perform
[segue perform];
[segue.sourceViewController.navigationController pushViewController:segue.destinationViewController animated:YES];
30.延遲執(zhí)行代碼方法?
- GCD的dispatch_after方法
31.ios當中的存儲方式有哪些赡艰?
plist存儲
preference偏好設置
NSKeyedArchive歸檔
SQLLite存儲
CoreData存儲
32.簡述ios應用沙盒的概念售淡?
每個ios應用都有自己的應用沙盒(應用沙盒就是文件系統(tǒng)目錄),與其他文件系統(tǒng)隔離
應用必須待在自己的沙盒里慷垮,其他應用不能訪問該沙盒
33.沙盒目錄結構
Documents:保存應用運行時生成的需要持久化的數據揖闸,iTunes同步設備的時候會備份該目錄
tmp:保存應用運行時所需要的臨時數據,使用完畢后再將相應的文件從該目錄刪除料身。應用沒有運行時汤纸,系統(tǒng)也可能會清除該目錄下的文件。
-
Library
Caches:保存應用運行時生成的需要持久化的數據芹血,iTunes同步設備時不會備份該目錄
Preference:保存應用的所有偏好設置贮泞,ios的setting設置應用會在該目錄中查找應用的設置信息
34.如何獲取沙盒目錄楞慈?
- NSDocumentDirectory:查找哪一個文件夾
- NSUserDomainMask:在什么范圍下查找
- expandTilde:是否展開路徑
- NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)[0]
35.NSUserDefaults的實現(xiàn)是什么存儲?一般用來存什么啃擦?
- NSUserDefaults不需要考慮文件名稱跟文件的路徑
- NSUserDefaults本質就是plist存儲(NSDictionary)
- 在NSUserDefaults中囊蓝,key值不能為nil
- 在NSUserDefaults也不能存放自定義的對象
- 一般用來存用戶的一些偏好,如版本號令蛉,密碼聚霜,賬號等
36.歸檔一般用來保存什么?使用時有哪些注意點珠叔?
- 歸檔一般用來保存自定義的對象蝎宇,使用歸檔的時候,要告訴保存的對象
- encodeWithCoder:保存該對象的哪些屬性
- initWithCoder:詢問你要讀取該對象的哪些屬性
37.initWithCoder祷安,什么時候調用姥芥?與awakeFromNib的區(qū)別?
- initWithCoder:當開始解析一個文件的時候調用汇鞭,如果一個view是從xib當中加載凉唐,當開始解析xib時會調用這個方法,在調用這個方法的時候霍骄,里面的子控件都還沒有創(chuàng)建
- awakeFromNib:當前對象從nib文件當中加載完結時調用熊榛,awakeFromNib調用時,說明xib加載完結了腕巡,view的大小和里面子控件的尺寸都已經知道了
38.使用導航控制器有哪些注意點玄坦?
- 凡是在導航控制器下的scrollView都會自動設置一個內邊距64
- 可以使用automaticallyAdjustsScrollViewInsets屬性取消內邊距
- 導航條以及導航條里面的控件設置透明度是沒有效果的
- 如果不設置背景圖片,會默認設置一張透明的圖片
- 只要是想要設置背景圖片绘沉,必須得要使用UIBarMetricsDefault樣式
- 同一個導航控制器下煎楣,導航條只有一個
39.UITabBarController的基本使用
- 初始化UITabBarController控制器
- 設置為窗口的根控制器為UITabBarController
- 創(chuàng)建對應的子控制器
- 調用UITabBarController的addChildViewController添加子控制器
- 默認選中的是第一個添加的子控制器
- 可以通過tabBar.selectedIndex的屬性更改選中的控制器
- 內部有多少個子控制器,底部tabBar條上就有多少個按鈕
- 每一個子控制器的view都是懶加載
40.如何設置TabBar的內容车伞?
- UITabBarButton里面顯示什么內容择懂,由對應子控制器的tabBarItem屬性決定
- 設置標題
- vc1.tabBarItem.title = @"標題1";
- 設置提醒數字
- vc1.tabBarItem.badgeValue = @"10";
- 添加子控制器.
- [tabBar addChildViewController:vc1];
41.事件的傳遞過程?(掌握)
- 當發(fā)生一個觸摸事件后另玖,系統(tǒng)會將該事件加入到一個由UIApplication管理的事件隊列中
- UIApplication會從事件隊列中取出最前面的事件困曙,交給主窗口
- 主窗口會在視圖層次結構中找到一個最合適的視圖來處理觸摸事件
- 觸摸事件的傳遞是從父控件傳遞到子控件
- 如果一個父控件不能接收事件,那么它里面的子控件也不能夠接收事件
42.一個控件什么情況下不接收事件谦去?
- 不接收用戶交互時不能夠處理事件
- userInteractionEnabled NO
- 當一個控件隱藏的時候不能夠接收事件
- hidden YES
- 當一個控件為透明的時候慷丽,也不能夠接收事件
- 注意:UIImageView的userInteractionEnabled默認就是NO,因此UIImageView已經它的子控件默認是不能夠接收觸摸事件的
43.如何尋找最適合的view?
- 先判斷自己是否能夠接收觸摸事件,如果能再繼續(xù)往下判斷
- 再判斷觸摸的當前點在不在自己身上
- 如果在自己身上鳄哭,它會從后往前遍歷子控件要糊,遍歷出每一個子控件后,重復前面的兩個步驟
- 如果沒有符合條件的子控件妆丘,那么他自己就是最適合的view
44.事件的響應過程
- 用戶點擊屏幕后產生的一個觸摸事件锄俄,經過一系列的傳遞過程后局劲,會找到最合適的視圖控件來處理這個事件
- 找到最適合的視圖控件后,會調用控件的touches方法來做具體的事件處理
- 這些touches的默認做法是將事件順著響應者鏈條向上傳遞奶赠,將事件交給上一個響應者進行處理
45.如何尋找上一個響應者
- 如果當前view是控制器的view,那么控制器就是上一個響應者
- 如果當前的view不是控制器的view,那么他的父控件就是上一個響應者
- 在視圖層次結構的最頂級視圖鱼填,如果也不能處理收到的事件或消息,則其將事件或者消息傳遞給window對象進行處理
- 如果window對象也不處理毅戈,則其將事件或消息傳遞給UIApplication對象
- 如果UIApplication也不能處理該事件或消息剔氏,則將其丟棄
46.transform帶Make與不帶Make的區(qū)別?
- 帶Make:是相對于最原始的形變竹祷,使用情況為只做一次形變操作
- 不帶Make:是相對于上一次的形變,使用情況為多次形變操作
47.如何添加手勢
- 創(chuàng)建手勢
- 添加手勢
- 實現(xiàn)手勢方法
48.如何同時支持多個手勢
- 想要同時支持多個手勢羊苟,要通過代理的方法
- 設置代理塑陵,在實現(xiàn)是否支持允許多個手勢的代理方法中,返回YES
49.hitTest:方法的作用以及什么時候調用
- 作用:尋找最適合的view
- 參數:當前手指所在的點蜡励,產生的事件
- 返回值:返回誰令花,誰就是最適合的view
- 什么時候調用,只要一個事件凉倚,傳遞給一個控件的時候兼都,就會調用這個控件的hitTest方法
50.pointInSide方法的作用以及有什么注意點?
- 作用:判斷point在不在方法調用者上
- point:必須是方法調用者的坐標系
- 什么時候調用:hitTest方法底層會調用這個方法稽寒,判斷點在不在控件上
51.什么是圖形上下文扮碧?
- 圖形上下文是用來保存用戶繪制的內容狀態(tài),并決定繪制到哪個地方的.
- 用戶把繪制好的內容先保存到圖形上下文,
- 然后根據選擇的圖形上下文的不同,繪制的內容顯示到地方也不相同,即輸出目標也不相同.
52.如何自定義UIView,步驟是什么杏糙?
- 首先得要有上下文,有了上下文才能決定把繪制的東西顯示到哪個地方去.
- 其次就是這個上下文必須得和View相關聯(lián).才能將內容繪制到View上面.
- 步驟:
- 1.要先自定定UIView
- 2.實現(xiàn)DrawRect方法
- 3.在DrawRect方法中取得跟View相關聯(lián)的上下文.
- 4.繪制路徑(描述路徑長什么樣).
- 5.把描述好的路徑保存到上下文(即:添加路徑到上下文)
- 6.把上下文的內容渲染到View
53.DrawRect方法作用?什么時候調用慎王?
- DrawRect作用:專用在這個方法當中繪圖的.只有在這個方法當中才能取得跟View相關聯(lián)的上下文.
- DrawRect是系統(tǒng)自己調用的, 它是當View顯示的時候自動調用.
54.setNeedsDisplay方法的作用
- 當每次調用setNeedsDisplay這個方法,系統(tǒng)就會自動調用drawRect
- 當我們手動調用drawRect:方法時, 它并不會給我們創(chuàng)建跟VIEW相關聯(lián)的上下文.
- 只有系統(tǒng)自動調用drawRect方法的時候才會創(chuàng)建跟View相關聯(lián)的上下文.
- setNeedsDisplay底層會調用DrawRect方法重繪.
- 但是它不是立馬就進行重繪.它僅僅是設置了一個重繪標志,等到下一次屏幕刷新的時候才會調用DrawRect方法.
55.如何畫文字?
- 先創(chuàng)建好要畫的文字
- 使用UIKit提供的方法進行繪制.
- 方法說明:
- drawAtPoint:要畫到哪個位置
- withAttributes:文本的樣式.
- [str drawAtPoint:CGPointZero withAttributes:nil];
56.如果畫圖片?
- 繪制圖片同樣開始要先把圖片素材導入.
- AtPoint:參數說明圖片要繪制到哪個位置.
- 通過調用UIKit的方法drawAtPoint:CGPointZero方法進行繪制;
- drawAtPoint:繪制出來的圖圖片跟圖片的實際尺寸一樣大
- drawInRect:使用這個方法繪制出來的圖片尺寸會和傳入的rect區(qū)域一樣大.
- 平鋪圖片
- [image drawAsPatternInRect:rect];
57.如何使用CADisplayLink添加定時器
- Target:哪個對象要監(jiān)聽方法.
- selector:監(jiān)聽的方法名稱.
- CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];
- 想要讓CADisplayLink工作,必須得要把它添加到主運行循環(huán).
- 只要添加到主運行循環(huán), 跟模式沒有關系
- [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
58.什么是上下文狀態(tài)棧宏侍?
- 上下文狀態(tài)棧為內存中的一塊區(qū)域赖淤,用來保存上下文當前的狀態(tài)
- 我們獲取的圖層上下文當中其實有兩塊區(qū)域:一個是存放添加的路徑,一個是用來保存用戶設置的狀態(tài)
- 這些狀態(tài)包括線條的顏色谅河、線寬等
- 當我們把上下文的內容渲染到view上面的時候
- 它會自動將設置的所有上下文狀態(tài)運行到保存的路徑上面顯示到view上面
59.如何保存和恢復上下文狀態(tài)
- 保存
- CGContextSaveGState(context)
- 恢復
- CGContextRestoreGState(context)
60.上下文矩陣操作有哪些咱旱?
上下文的矩陣操作,就是上下文當中的路徑可以進行一些形變操作
平移CGContextTranslateCTM()
旋轉CGContextScaleCTM()
縮放CGContextRotate()
注意相比操作要在添加路徑之前進行
61.如何生成一張圖片绷耍?
- 開啟一個圖片上下文.
- 上下文的大小和原始圖片保持一樣.以免圖片被拉伸縮放.
- 在上下文的上面添加一個圓形裁剪區(qū)域.圓形裁剪區(qū)域的半徑大小和圖片的寬度一樣大.
- 把要裁剪的圖片繪制到圖片上下文當中.
- 從上下文當中取出圖片.
- 關閉上下文.
62.如何把圖片轉成二進制流吐限?
- 把生成的圖片寫到桌面上.
- 桌面都是以流的形式傳遞數據,所以我們要把圖片轉成二進流.
- image:要轉的圖片
- compressionQuality:壓縮質量,1代表質量最高
- NSData *data = UIImageJPEGRepresentation(newImage, 1);
- 原始質量的png圖片.
- NSData *data = UIImagePNGRepresentation(newImage);
- 把二進流寫到桌面.
- [data writeToFile:@"/Users/gaoxinqiang/Desktop/newImage.png" atomically:YES];
63.如何把一個路徑設置為裁剪區(qū)域?
- 利用UIBezierPath設置一個矩形的裁剪區(qū)域.
- 然后把這個路徑設置為裁剪區(qū)域.
- 把路徑設為裁剪區(qū)域的方法為:
- [path addClip];
64.如何擦除上下文當中的某一個區(qū)域褂始?
獲取當前的上下文.
CGContextRef ctx = UIGraphicsGetCurrentContext();
把UIImageV上的圖片渲染到上下文當中.
[self.imageV.layer renderInContext: ctx];
設置擦除區(qū)域
CGContextClearRect(ctx, rect);
65.如何判斷點在不在某個區(qū)域當中
判斷手指當前點在不在按鈕上.
if (CGRectContainsPoint(btn.frame, point)) {
在按鈕上.返回當前按鈕
return btn;
}
66.如何把圖片保存到系統(tǒng)相冊毯盈?
- 調用方法:
- 參數說明:
- 第一個參數:要寫入到相冊的圖片.
- 第二個參數:哪個對象堅聽寫入完成時的狀態(tài).
- 第三個參數:圖片保存完成時調用的方法
UIImageWriteToSavedPhotosAlbum(newImage,self,@selector(image:didFinishSavingWithError: contextInfo:),nil);
注意:圖片保存完成時調用的方法必須得是image:didFinishSavingWithError: contextInfo:
67.如何從系統(tǒng)相冊當中選擇一張照片?
彈出系統(tǒng)相冊
UIImagePickerController *vc = [[UIImagePickerController alloc] init];
設置照片的來源
vc.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
vc.delegate = self;
Modal出來系統(tǒng)相冊
[self presentViewController:vc animated:YES completion:nil];
調用代理方法:-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
68.如何辦到一個圖片長按的時候閃一下病袄?
- 先通過一個動畫,把圖片的alpha值改為0.
- 在動畫完成時, 立馬再通過一個動畫設置為1.
69.抽取方法的思路搂赋?
- 抽取一個方法時,要做到方法的功能單一性, 不要一個方法里面寫過多的業(yè)務邏輯, 要方便適合更多場合
- 相同的代碼,寫到一個方法當中 ,不同的地方當做參數傳入.
70.什么情況下自定義類赘阀?
- 當發(fā)現(xiàn)系統(tǒng)的類沒有辦法瞞足自己要求時, 可以繼續(xù)系統(tǒng)的類, 在子類當中添加屬性自己的類屬性.
71.什么是CALayer?
- CALayer我們又稱它叫做層.
- 在每個UIView內部都有一個layer這樣一個屬性.
- UIView之所以能夠顯示,就是因為它里面有這個一個層,才具有顯示的功能.
- 我們通過操作CALayer對象,可以很方便地調整UIView的一些外觀屬性.
- 可以給UIView設置陰影,圓角,邊框等等…
72.如何自定義Layer?
- 自定義CALayer的方式創(chuàng)建UIView的方式非常相似.
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(50, 50, 100, 100);
layer.backgroundColor = [UIColor redColor].CGColor;
[self.view.layer addSublayer:layer];
73.UIView和CALayer都能夠顯示東西,該怎么選擇脑奠?
- 對比CALayer基公,UIView多了一個事件處理的功能。也就是說宋欺,CALayer不能處理用戶的觸摸事件轰豆,而UIView可以
- 如果顯示出來的東西需要跟用戶進行交互的話,用UIView齿诞;
- 如果不需要跟用戶進行交互酸休,用UIView或者CALayer都可以
- CALayer的性能會高一些,因為它少了事件處理的功能祷杈,更加輕量級
74.layer的CATransform3D屬性是干什么用的斑司?
旋轉
x,y,z 分別代表x,y,z軸.
CATransform3DMakeRotation(M_PI, 1, 0, 0);
平移
CATransform3DMakeTranslation(x,y,z)
縮放
CATransform3DMakeScale(x,y,z);
可以通過KVC的方式進行設置屬性.
但是CATransform3DMakeRotation它的值,是一個結構體, 所以要把結構轉成對象.
NSValue *value = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 1, 0, 0)];
[_imageView.layer setValue:value forKeyPath:@"transform.scale"];
75.position和anchorPoint是CALayer的兩個屬性,作用但汞?
- 我們以前修改一個控件的位置都是能過Frame的方式進行修改.
- 現(xiàn)在利用CALayer的position和anchorPoint屬性也能夠修改控件的位置.
- 這兩個屬性是配合使用的.
- position:它是用來設置當前的layer在父控件當中的位置的.所以它的坐標原點.以父控件的左上角為(0.0)點.
- 兩者結合使用.想要修改某個控件的位置,我們可以設置它的position點.
- 設置完畢后.layer身上的anchorPoint會自動定到position所在的位置.
76.什么是隱式動畫宿刮?
- 根層:UIView內部自動關聯(lián)著的那個layer我們稱它是根層.
- 非根層:自己手動創(chuàng)建的層,稱為非根層.
- 隱式動畫就是當對非根層的部分屬性進行修改時, 它會自動的產生一些動畫的效果.
- 我們稱這個默認產生的動畫為隱式動畫.
77.如何獲取當前時間?
- 創(chuàng)建日歷類
- NSCalendar *calendar = [NSCalendar currentCalendar];
- 把日歷類轉換成一個日期組件
- 日期組件(年,月,日,時,分,秒)
- component:日期組件有哪些東西組成,他是一個枚舉,里面有年月日時分秒
- fromDate:當前的日期
- NSDateComponents *cmp = [calendar components:NSCalendarUnitSecond fromDate:[NSDate date]];
- 我們的秒就是保存在日期組件里面,它里面提供了很多get方法.
- NSInteger second = cmp.second;
78.ios中所有的旋轉和縮放都是繞著哪個點進行的?
- ios中所有的旋轉與縮放都是繞著錨點進行的
- 只要修改錨點,就會讓旋轉,與縮放的點發(fā)生變化.
79.CoreAnimation的使用步驟
- 1.初始化一個CAAnimation對象私蕾,并設置一些動畫相關屬性
- 2.通過調用CALayer的addAnimation:forKey:方法增加CAAnimation對象到CALayer中僵缺,這樣就能開始執(zhí)行動畫了
- 3.通過調用CALayer的removeAnimationForKey:方法可以停止CALayer中的動畫
80.UIView和核心動畫對比?
- 1.UIView和核心動畫區(qū)別?
- 核心動畫只能添加到CALayer
- 核心動畫一切都是假象踩叭,并不會改變真實的值磕潮。
- 2.什么時候使用UIView的動畫?
- 如果需要與用戶交互就使用UIView的動畫.
- 不需要與用戶交互可以使用核心動畫
- 3.什么場景使用核心動畫最多?
- 在轉場動畫中,核心動畫的類型比較多
- 根據一個路徑做動畫容贝,只能用核心動畫(幀動畫)
- 動畫組:同時做多個動畫
81.如何讓按鈕成為選中狀態(tài)揉抵?取消按鈕的高亮狀態(tài)?
- 1.在添加按鈕時嗤疯,給每一個按鈕添加選中狀態(tài)
- 添加按鈕事件的時候要注意冤今,如果按鈕添加到UIImageView上的,UIImageView默認是不接收事件的茂缚,所以需要手動把UIImageView設置為可接收事件
- 2.讓按鈕成為選中狀態(tài)
- 在事件處理方法當中戏罢,我們要先定義一個成員屬性記錄上一個按鈕的選中狀態(tài)
- 先把上一個按鈕的選中狀態(tài)取消選中
- 把當前點擊的按鈕設置為選中狀態(tài)
- 把當前的按鈕賦值給上一個按鈕
- 3.取消按鈕的高亮狀態(tài)
- 自定義按鈕
- 重寫按鈕的setHighlighted:方法
82.如何從一張大圖當中截取某一部分為圖片?
- 首先要確定裁剪的區(qū)域脚囊,即每一張圖片的寬高
- 每一張圖片的高度龟糕,為原始圖片的高度
- 每一張圖片的寬度,為整個圖片的寬度除以總共需要裁剪的圖片的數量悔耘。
- 方法:CGImageCreateWithImageInRect(image,rect)
- image:為要裁剪的圖片(原始圖片)讲岁,它的類型為CGImageRef類型,所以要轉成CGImage
- rect:為裁剪的范圍,這時需要確定每一個x的位置
- 每一個x為當前的角標*要裁剪的寬度
- 這個方法它會返回一個圖片缓艳,圖片類型為CGImageRef image,所以要在設置背景圖片的時候校摩,要把這張圖片給轉成UIImage
- 轉化的方法:UIImage *image = [UIImage imageWithCGImage:image]
83.如何讓一張圖片只顯示上半部分或者下半部分?
-
利用CALayer的一個屬性 contentsRect = CGRectMake(0,0,1,0.5)
- contentsRect就是要顯示的范圍阶淘,它的取值范圍是0~1
想讓上部圖片只顯示上半部分contentsRect設置CGRectMake(0,0,1,0.5)
下半部分圖片只顯示下半部分contentsRect設置為CGRectMake(0,0.5,1,0.5)
84.如何設置漸變效果衙吩?
我們可以通過CAGradientLayer這個層來創(chuàng)建漸變,這個層我們就稱它是一個漸變層溪窒。
漸變層也是需要添加到一個層上面才能夠顯示
漸變層里面有一個colors屬性坤塞,這個屬性就是設置要漸變的顏色,他是一個數組澈蚌,數組當中要求我們傳入CGColorRef類型摹芙,所以我們要把顏色轉成CGColor,但是轉成CGColor后宛瞄,數組就認識它是一個對象了浮禾,就要通過在前面加上一個(id)來告訴編譯器是一個對象
-
設置漸變的方向
- startPoint
- endPoint
- 取值范圍0~1
-
默認方向為上下漸變
- startPoint = CGPointMake(0,0)
- endPoint = CGPointMake(0,1)
-
設置左右漸變
- startPoint = CGPointMake(0,0)
- endPoint = CGPointMake(1,0)
85.在手指拖動的過程當中,松開手指時坛悉,有一個動畫反彈回去的效果是如何做到的?
-
[UIView animateWithDuration:0.8 delay:0 usingSpringWithDamping:0.1 initialSpringVelocity:0
options:UIViewAnimationOptionCurveLinear
animations:^{
動畫執(zhí)行代碼
} completion:^(BOOL finished) {
動畫完成時調用.
}];- Duration:動畫的執(zhí)行時長
- delay:動畫延時時長.
- Damping:動畫的彈性系數,越小,彈簧效果越明顯
- initialSpringVelocity:彈簧初始化速度
86.如何使用復制層承绸?
- 添加復制層裸影,首先先要讓這個層顯示出來
- 復制層必須加到一個層里面才能夠復制它的子層
- 不需要設置它的尺寸,需要設置它的顏色军熏,子層超過父層也能夠顯示轩猩,所以不用設置尺寸
- CAReplicatorLayer *replicator = [CAReplicatorLayer layer];
- 將復制層添加到_contententView.layer
[_contentsView.layer addSublayer:replicator];
instanceCount:表示原來層中的所有子層復制的份數
replicator.instanceCount = 2;
在復制層中添加子層
[replicator addSublayer:layer];
87.如何使用形狀圖層?
- 形式為
- (CAShapeLayer *)shape{
if(_shape == nil){
//創(chuàng)建形狀圖層
CAShapeLayer *shape = [CAShapeLayer layer];
//設置形狀圖層的填充顏色
shape.fillColor = [UIColor redColor].CGColor;
self.shape = shape;
//把形狀圖層添加到當前按鈕的父層當中
[self.superview.layer insertSublayer:shape atIndex:0];
_shape = shape;
}
return _shape;
}
88.拖動的時候如何讓它有一個立體的效果荡澎?
- 立體的效果就是有一種近大遠小的感覺.
- 想要設置立體效果.要修改它的TransForm當中的一個M34值,設置方式為弄一個空的TransFrom3D
- CATransform3D transform = CATransform3DIdentity;
- transform.m34 = - 1 / 200.0;
- 200.0可以理解為均践,人的眼睛離手機屏幕的垂直距離,近大遠小效果越明顯
- transform = CATransform3DRotate(transform, angle, 1, 0, 0);
- 相對上一次改了m34的形變,再去旋轉
89.如何通過layer改變UIView的外觀摩幔?
-
默認圖層是有陰影的, 只不過,是透明的
- _RedView.layer.shadowOpacity = 1;
-
設置陰影的圓角
- _RedView.layer.shadowRadius =10;
-
設置陰影的顏色,把UIKit轉換成CoreGraphics框架,用.CG開頭
- _RedView.layer.shadowColor = [UIColor blueColor].CGColor;
設置邊框
-
設置圖層邊框,在圖層中使用CoreGraphics的CGColorRef
- _RedView.layer.borderColor = [UIColor whiteColor].CGColor;
- _RedView.layer.borderWidth = 2;
設置圓角
-
圖層的圓角半徑,圓角半徑為寬度的一半, 就是一個圓
- _RedView.layer.cornerRadius = 50;
操作layer改變UIImageView的外觀.
-
設置圖形邊框
- _imageView.layer.borderWidth = 2;
- _imageView.layer.borderColor = [UIColor whiteColor].CGColor;
90.position和anchorPoint如何使用彤委?
- 這兩個屬性是配合使用的.
- position:它是用來設置當前的layer在父控件當中的位置的.
- 所以它的坐標原點.以父控件的左上角為(0.0)點.
- anchorPoint:它是決點CALayer身上哪一個點會在position屬性所指的位置
- anchorPoint它是以當前的layer左上角為原點(0.0)
- 它的取值范圍是0~1,它的默認在中間也就是(0.5,0.5)的位置.
- anchorPoint又稱錨點.就是把錨點定到position所指的位置.
91.為什么要自定義類?
- 當發(fā)現(xiàn)系統(tǒng)的類無法滿足我們的需求的時候或衡,想要在系統(tǒng)的功能上添加一些自己的功能焦影,這個時候就可以自定義類
- 新建一個類,繼承自系統(tǒng)的類封断,添加一些屬于自己的功能
- 比如在做畫板的時候斯辰,自定義了UIBeizierPath
- 想要讓代碼的結構更加清晰,便于閱讀(做到誰的事情誰管理)
92.自定義tabBar的實現(xiàn)思路
- 把系統(tǒng)的tabBar移除
- tabBar中的按鈕個數坡疼,和按鈕顯示什么樣的圖片由外界決定
- 外界傳入一個數組彬呻,數組中存放的都是UITabBarItem模型,有多少個模型就創(chuàng)建多少個按鈕,并設置內容
93.Block作用闸氮?
- 保存一段代碼
94.Block的定義方式剪况?
返回值類型(^Block名稱)(參數) = ^(參數){
保存的代碼
}
95.Block如何當做參數傳遞?
- 當發(fā)現(xiàn)某一塊的功能變化的時候湖苞,其他地方沒有變化拯欧,此時,可以把變化的地方利用block的方式财骨,當做參數傳入镐作。
96.如何進行解耦?
- 第一種方式:代理
- 第二種方式:block
97.如何自定義遮蓋?
- 自定義的遮蓋是顯示到最外面的,顯示到最外面的東西罢绽,我們要添加到主窗口上
- 通過UIApplication的keyWindow拿到應用程序的窗口深浮,把遮蓋添加到窗口顯示出來
98.如何顯示與隱藏pop菜單?
- 顯示pop的方式吆视,提供顯示到某一個點的方法,同樣是添加到窗口上面,提供隱藏到某一個點的方法
- 通過動畫的方式進行隱藏逞力,隱藏完畢的時候,通過block方式傳入糠爬,由外界決定做什么事情寇荧。
99.如何全局修改導航條的屬性?
- 通過Appearance的方式拿到整個應用程序的導航條
- 獲取指定類下的導航條
- UINavigationBar * bar = [UINavigationBar appearanceWhenContainedInstancesOfClasses:@[self class]];
100.分類中如何添加屬性执隧,應該注意哪些揩抡?
- 分類當中如果要添加屬性的話,就必須要實現(xiàn)該屬性的set與get方法镀琉,如果不寫的話峦嗤,要自動生成get、set方法
- 在分類中屋摔,使用@property不會生成帶有下劃線的成員屬性烁设,只會聲明它的set和get方法
101.initialize
- initialize 當前類或者子類第一次使用的時候調用
- 如果子類也寫了initialize方法,那么會先調用父類的initialize方法钓试,再調用子類的initialize;如果子類沒有寫initialize署尤,那么會調用兩次父類的initialize,可以根據[self class]判斷是誰先調用的
- [self class]和[super class] 是同一個對象
- super是優(yōu)先找它父類的方法
- initialize不只調用一次
102.字符串是用strong還是用copy
理論上應該用copy亚侠,但是在實際開發(fā)中由于字符串大多是不可變的曹体,所有常用strong修飾
-
為什么用copy?
- 外界修改時,不會影響里面的值
-
為什么聲明為copy時不會影響到里面的值硝烂?
- 使用copy時會生成新的內存地址箕别,使用strong的時候,用的是同一個內存地址
copy的set方法是怎么寫的?
- (void) setName:(NSString *)name{
_name = [name copy]
}
- 當使用的是不可變字符串的時候串稀,是不會生成新的內存地址的
- 如果是不可變的字符串當使用copy的時候除抛,它會多做一次判斷,判斷是否為可變
- 在開發(fā)當中使用的字符串大多數是不可變的母截,比如從網絡加載的字符串大多是不可變的到忽,plist中的字符串也是不可變的
- 所以不可變的字符串使用strong性能會好一些。
103.如何通過代碼拉伸圖片清寇?
//取出背景圖片
UIImage *image = self.loginBtn.currentBackgroundImage;
//拉伸圖片的中間區(qū)域
UIImage * stretchImage = [image stretchImageWithLeftCapWidth:image.size.width *0.5 topCapHeight:image.size.height *0.5]
[self.loginBtn setBackgroundImage:stretchImage forState:UIControlStateNormal]
104.static關鍵字的作用喘漏?
- 函數(方法)體內,static變量的作用范圍為該函數體华烟,該變量的內存只被分配一次翩迈,因此其值在下次調用的時候仍維持在上次的值
- 在模塊內的static全局變量可以被模塊內所有函數訪問,但不能被模塊外其他函數訪問
- 在模塊內的static函數只可被這一模塊內的其他函數調用盔夜,這個函數的使用范圍被限制在聲明它的模塊內负饲;
- 在類中static 成員變量屬于屬于整個類擁有,對類的所有對象只有一份拷貝
- 在類中的static成員函數屬于整個類所擁有喂链,這個函數不接受指針返十,因而只能訪問類的static成員變量
105.如何全局修改返回按鈕?
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (self.childViewControllers.count != 0) {
NSLog(@"非根控制器");
//設置返回按鈕
viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageWithOriImageName:@"NavBack"] style:0 target:self action:@selector(back)];
//重寫了系統(tǒng)返回,那么系統(tǒng)的側滑返回功能就會失效
self.interactivePopGestureRecognizer.delegate = nil;
//當push時隱藏系統(tǒng)底部Tabbar
viewController.hidesBottomBarWhenPushed = YES;
}
[super pushViewController:viewController animated:animated];
}
106.如何恢復側滑返回功能椭微?
- 側滑返回是一個手勢洞坑,重寫返回按鈕的時候,側滑返回手勢會通過它的代理赏表,不去做任務事情
- 把系統(tǒng)的側滑返回手勢的代理清空
- 清空手勢代理帶來的問題
- 當是根控制器的時候检诗,還要把側滑返回的手勢代理給設置回去
107.如何添加全屏幕滑動返回匈仗?
- 給導航控制器的view添加拖動手勢
- 讓拖動手勢的事件調用系統(tǒng)的側滑返回方法
108.通過scrollView實現(xiàn)無限輪播思路瓢剿?
1.確定圖片的寬度等于scrollViewW
2.設置scollView 的contentSize (3 * W,H)
3.把scollView的offset.x設置為一個W
4.創(chuàng)建兩個imageV, centerImageV * reuseImageV
5.設置centerImageV .x = W
6. reuseImageV.x = maxX(centerImageV .frame)
7.當scorllView滾動時,判斷offset.x是否大于2 * W
立馬把offset.x設置為W
交換兩個ImageView的位置
8.交換兩個指針
109.UICollectionViewController使用的注意點?
- 創(chuàng)建CollectionViewController必須得要初始化一個布局參數
- UICollectionViewCell必須得要自己手動去注冊
- UICollectionViewCell默認內部并沒有子控件悠轩,需要我們手動的去添加间狂,自定義cell
110.流水布局屬性有哪些?
//流水布局
UICollectionViewFlowLayout *flowL = [[UICollectionViewFlowLayout alloc] init];
//設置每一個格子的大小
flowL.itemSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
//設置最小行間距
flowL.minimumLineSpacing = 0;
//設置每個格子之間的間距
flowL.minimumInteritemSpacing = 0;
//設置滾動的方向
flowL.scrollDirection = UICollectionViewScrollDirectionHorizontal;
111.initialize方法的作用火架?
- 該方法是當前類或者它的子類第一次使用的時候會調用
112.新特性業(yè)務邏輯是怎樣的鉴象?
- 獲取當前軟件的版本號
- 判斷當前版本是否與之前的版本相同
- 相同,跳到程序的主框架
- 不同何鸡,跳到新特性纺弊,保存當前的版本號
113.如何切換根控制器?
- 點擊立即體驗按鈕的時候骡男,跳轉到程序的主框架
- 新特性界面已經不需要出現(xiàn)了淆游,新特性界面現(xiàn)有窗口的根控制器強引用
- 所以把窗口的根控制器指向程序的主框架,新特性界面就會被釋放掉
114.為什么要抽取業(yè)務類?
- 讓代碼具有更強的擴展性
- 讓代碼的結構更加的清晰
- 減少第三方框架對程序的污染
115.KVO內部實現(xiàn)原理犹菱?
- KVO是基于runtime機制實現(xiàn)的
- 當某個類的屬性對象第一次被觀察時拾稳,系統(tǒng)就會在運行期動態(tài)地創(chuàng)建該類的一個派生類,在這個派生類中重寫基類中任何被觀察屬性的setter 方法腊脱。派生類在被重寫的setter方法內實現(xiàn)真正的通知機制
- 如果原類為Person访得,那么生成的派生類名為NSKVONotifying_Person
- 每個類對象中都有一個isa指針指向當前類,當一個類對象的第一次被觀察陕凹,那么系統(tǒng)會偷偷將isa指針指向動態(tài)生成的派生類悍抑,從而在給被監(jiān)控屬性賦值時執(zhí)行的是派生類的setter方法
- 鍵值觀察通知依賴于NSObject 的兩個方法: willChangeValueForKey: 和 didChangevlueForKey:;在一個被觀察屬性發(fā)生改變之前捆姜, willChangeValueForKey: 一定會被調用传趾,這就 會記錄舊的值。而當改變發(fā)生后泥技,didChangeValueForKey: 會被調用浆兰,繼而 observeValueForKey:ofObject:change:context: 也會被調用。
116.如何把一個字符串轉成類名珊豹?
NSClassFromString(<#NSString * _Nonnull aClassName#>) 通過類型,就可以去創(chuàng)建一個對象.
117.block使用的注意點有哪些簸呈?
- 在使用block前需要對block指針做判斷處理
- 在MRC的編譯環(huán)境下,block如果作為成員參數要copy一下將棧上的block拷貝到堆上
- 在block使用之后要對block指針做賦空值處理店茶,如果是MRC的編譯環(huán)境下蜕便,要先release掉block對象,block作為類對象的成員變量贩幻,使用block的人有可能用類對象參與block中的運算而產生循環(huán)引用
- 使用方將self或者成員變量加入block之前要先將self變?yōu)開weak
- 在多線程環(huán)境下(block中的weakSelf有可能被析構的情況下)需要先將self轉為strong指針轿腺,避免在運行到某個關鍵步驟的時候self對象被析構。
118.UITableView優(yōu)化技巧丛楚?
- 1.正確的使用cell標識,緩存池.(必須講)
- 2.提前計算好行高.因為heightForRowAtIndexPath:是調用最頻繁的方法,不要在該方法當中使用indexPath獲取行返回行高
- 3.如果cell內容非常多的時候可以在異步線程當中進行繪制.
- 4.cell的內容來自網絡時,一定要異步加載.把請求的結果緩存起來.
- 5.減小subView的數量.
- 6.盡量少用或者不用透明圖片圖層.,渲染系統(tǒng)就認為這個view是完全不透明的族壳,這使得渲染系統(tǒng)優(yōu)化一些渲染過程和提高性能。
- 7.盡量少用addSubView給cell添加子控件,可以初始化的時候就添加好.然后通過hidden來控件顯示.
- 8.在Cell中來自網絡圖片時,UIImageView的圖片最好跟來自網絡圖片一樣大.因為壓縮圖片是非常耗費資源的,其實做的是變形transform操作,每一次的壓縮圖片都要乘以一個變換矩陣,
- 9.設置陰影時盡量不要使用offset,使用shadowPath這種方法,這個會比使用offset性能要高, offset會讓系統(tǒng)先描述好形狀,然后再添加陰影.
- 10.在View設置Frame時,盡量避免使用小數點.使用取整,或四舍5入
119.如何解決通過drawRect方法進行繪制內存增大問題趣些?
使用CALayer的方式進行繪制
CAShapeLayer是一個通過矢量圖形而不是bitmap來繪制的圖層子類仿荆。用CGPath來定義想要繪制的圖形,CAShapeLayer會自動渲染坏平。它可以完美替代我們的直接使用Core Graphics繪制layer拢操,對比之下使用CAShapeLayer有以下優(yōu)點:
渲染快速。CAShapeLayer 使用了硬件加速舶替,繪制同一圖形會比用 Core Graphics 快很多令境。
高效使用內存。一個 CAShapeLayer 不需要像普通 CALayer 一樣創(chuàng)建一個寄宿圖形顾瞪,所以無論有多大舔庶,都不會占用太多的內存返劲。
不會被圖層邊界剪裁掉。
不會出現(xiàn)像素化栖茉。
120.如何高性能的給UIImageView加一個圓角篮绿?
- 不好的解決方案是使用layer,使用layer的方式會強制Core Animation提前渲染屏幕的離屏繪制, 而離屏繪制就會給性能帶來負面影響,會有卡頓的現(xiàn)象出現(xiàn)
- 正確的解決方案:使用繪圖技術
- 還有一種方案:使用了貝塞爾曲線"切割"個這個圖片, 給UIImageView 添加了的圓角吕漂,其實也是通過繪圖技術來實現(xiàn)的
121.block和weak修飾符的區(qū)別亲配?
- _block不管是ARC還是MRC模式下都可以使用,可以修飾對象惶凝,也可以修飾基本數據類型
- _weak只能在ARC模式下使用吼虎,只能修飾對象(NSString),不能修飾基本數據類型
- block修飾的對象可以在block中被重新賦值苍鲜,weak修飾的對象不可以
122.如何封裝一個view?
- 可以通過純代碼或者xib的方式來封裝子控件
- 建立一個跟view相關的模型思灰,然后將模型數據傳給view,通過模型上的數據給view的子控件賦值