1.UDID和UUID
UDID
UDID的全名為Unique Device Identifier :設(shè)備唯一標識符。從名稱上也可以看出拍嵌,UDID這個東西是和設(shè)備有關(guān)的,而且是只和設(shè)備有關(guān)的斩例,有點類似于MAC地址赡勘。需要把UDID這個東西添加到Provisoning Profile授權(quán)文件中,也就是把設(shè)備唯一標識符添加進去楼熄,以此來識別某一臺設(shè)備忆绰。
UDID是一個40位十六進制序列,我們可以使用iTunes和Xcode來獲取這個值可岂。
自從iOS5之后错敢,蘋果就禁止了通過代碼訪問UDID,在這之前青柄,可以使用[[UIDevice cuurrent] uniqueIdenfier]
這個方法來獲取某設(shè)備UDID伐债。
蘋果提供了一個參數(shù)identifierForVendor來替代原來UDID的作用。
NSUUID *uuid = [UIDevice currentDevice].identifierForVendor;
NSLog(@"uuid 1 = %@",uuid.UUIDString);
此時打印出的字符串UUIDString這個東西不是真正的UDID致开,而是一個有一點像的替代品峰锁。UDID是只和iOS設(shè)備有關(guān)的,而這個identifierForVendor是應(yīng)用和設(shè)備兩者都有關(guān)的双戳,A應(yīng)用安裝到張三這臺設(shè)備上虹蒋,就會產(chǎn)生一個identifierForVendor(比如是:1234);A應(yīng)用安裝到李四這臺設(shè)備上飒货,就會產(chǎn)生另一個identifierForVendor(比如是:5678)魄衅。但是無論A應(yīng)用安裝卸載多少次,產(chǎn)生的是都是1234. 所以我們知道塘辅,這個identifierForVendor是一種應(yīng)用加設(shè)備綁定產(chǎn)生的標識符晃虫。也就是說App的開發(fā)者沒有辦法去區(qū)分某一臺設(shè)備了,而是只能識別某個應(yīng)用在某臺設(shè)備上扣墩。
UUID
英文名稱是:Universally Unique Identifier,翻譯過來就是通用唯一標識符哲银。是一個32位的十六進制序列,使用小橫線來連接:8-4-4-4-12 呻惕。UUID在某一時空下是唯一的荆责。比如在當前這一秒,全世界產(chǎn)生的UUID都是不一樣的亚脆;當然同一臺設(shè)備產(chǎn)生的UUID也是不一樣的做院。
NSString *uuid = [NSUUID UUID].UUIDString;
NSLog(@"uuid 2 = %@",uuid);
2.CPU和GPU
(1)概念
CPU(Central Processing Unit-中央處理器),是一塊超大規(guī)模的集成電路,是一臺計算機的運算核心(Core)和控制核心( Control Unit)濒持。它的功能主要是解釋計算機指令以及處理計算機軟件中的數(shù)據(jù)键耕。
CPU 的兩種工作狀態(tài):內(nèi)核態(tài)和用戶態(tài)(或者稱管態(tài)和目態(tài))。
內(nèi)核態(tài):系統(tǒng)中既有操作系統(tǒng)的程序弥喉,也由普通用戶的程序郁竟。為了安全和穩(wěn)定性操作系統(tǒng)的程序不能隨便訪問,這就是內(nèi)核態(tài),內(nèi)核態(tài)可以使用所有的硬件資源由境。
用戶態(tài):不能直接使用系統(tǒng)資源棚亩,也不能改變 CPU 的工作狀態(tài),并且只能訪問這個用戶程序自己的存儲空間虏杰。
GPU(Graphics Processing Unit-圖形處理器)讥蟆,是一種專門在個人電腦、工作站纺阔、游戲機和一些移動設(shè)備(如平板電腦瘸彤、智能手機等)上圖像運算工作的微處理器。
(2)緩存
CPU有大量的緩存結(jié)構(gòu)笛钝,目前主流的CPU芯片上都有四級緩存质况,這些緩存結(jié)構(gòu)消耗了大量的晶體管愕宋,在運行的時候需要大量的電力。
GPU的緩存就很簡單结榄,目前主流的GPU芯片最多有兩層緩存中贝,而且GPU可以利用晶體管上的空間和能耗做成ALU單元,因此GPU比CPU的效率要高一些臼朗。
(3)響應(yīng)方式
CPU要求的是實時響應(yīng)邻寿,對單任務(wù)的速度要求很高,所以就要用很多層緩存的辦法來保證單任務(wù)的速度视哑。
GPU是把所有的任務(wù)都排好绣否,然后再批處理,對緩存的要求相對很低挡毅。
(4)浮點運算方式
CPU除了負責浮點整形運算外蒜撮,還有很多其他的指令集的負載,比如像多媒體解碼慷嗜,硬件解碼等淀弹,因此CPU是多才多藝的。CPU注重的是單線程的性能庆械,要保證指令流不中斷薇溃,需要消耗更多的晶體管和能耗用在控制部分,于是CPU分配在浮點計算的功耗就會變少缭乘。
GPU基本上只做浮點運算的沐序,設(shè)計結(jié)構(gòu)簡單,也就可以做的更快堕绩。GPU注重的是吞吐量策幼,單指令能驅(qū)動更多的計算,相比較GPU消耗在控制部分的能耗就比較少奴紧,因此可以把電省下來的資源給浮點計算使用特姐。
(五)應(yīng)用方向
CPU所擅長的像操作系統(tǒng)這一類應(yīng)用,需要快速響應(yīng)實時信息黍氮,需要針對延遲優(yōu)化唐含,所以晶體管數(shù)量和能耗都需要用在分支預(yù)測、亂序執(zhí)行沫浆、低延遲緩存等控制部分捷枯。
GPU適合對于具有極高的可預(yù)測性和大量相似的運算以及高延遲、高吞吐的架構(gòu)運算专执。
3.堆淮捆、棧和隊列
(1)堆
堆是一種經(jīng)過排序的樹形數(shù)據(jù)結(jié)構(gòu),每個節(jié)點都有一個值,通常我們所說的堆的數(shù)據(jù)結(jié)構(gòu)是指二叉樹攀痊。所以堆在數(shù)據(jù)結(jié)構(gòu)中通惩╇纾可以被看做是一棵樹的數(shù)組對象。
堆需要滿足以下兩個性質(zhì):
1)堆中某個節(jié)點的值總是不大于或不小于其父節(jié)點的值苟径;
2)堆總是一棵完全二叉樹哩掺。
堆分為兩種情況,有最大堆和最小堆涩笤。
將根節(jié)點最大的堆叫做最大堆或大根堆,根節(jié)點最小的堆叫做最小堆或小根堆盒件,在一個擺放好元素的最小堆中蹬碧,父結(jié)點中的元素一定比子結(jié)點的元素要小,但對于左右結(jié)點的大小則沒有規(guī)定誰大誰小炒刁。
堆常用來實現(xiàn)優(yōu)先隊列恩沽,堆的存取是隨意的,這就如同我們在圖書館的書架上取書翔始,雖然書的擺放是有順序的罗心,但是我們想取任意一本時不必像棧一樣,先取出前面所有的書城瞎,書架這種機制不同于箱子渤闷,我們可以直接取出我們想要的書。
(2)棧
棧是限定僅在表尾進行插入和刪除操作的線性表脖镀。我們把允許插入和刪除的一端稱為棧頂飒箭,另一端稱為棧底,不含任何數(shù)據(jù)元素的棧稱為空棧蜒灰。棧的特殊之處在于它限制了這個線性表的插入和刪除位置弦蹂,它始終只在棧頂進行。
棧是一種具有后進先出的數(shù)據(jù)結(jié)構(gòu)强窖,又稱為后進先出的線性表凸椿,簡稱 LIFO(Last In First Out)結(jié)構(gòu)。也就是說后存放的先取翅溺,先存放的后取脑漫,這就類似于我們要在取放在箱子底部的東西(放進去比較早的物體),我們首先要移開壓在它上面的物體(放進去比較晚的物體)未巫。
堆棧中定義了一些操作窿撬。兩個最重要的是PUSH和POP。PUSH操作在堆棧的頂部加入一個元素叙凡。POP操作相反劈伴,在堆棧頂部移去一個元素,并將堆棧的大小減一。
棧的應(yīng)用——遞歸跛璧。
(3)隊列
隊列是只允許在一端進行插入操作严里、而在另一端進行刪除操作的線性表。允許插入的一端稱為隊尾追城,允許刪除的一端稱為隊頭刹碾。它是一種特殊的線性表废膘,特殊之處在于它只允許在表的前端進行刪除操作繁堡,而在表的后端進行插入操作,和棧一樣权旷,隊列是一種操作受限制的線性表色洞。
隊列是一種先進先出的數(shù)據(jù)結(jié)構(gòu)戏锹,又稱為先進先出的線性表,簡稱 FIFO(First In First Out)結(jié)構(gòu)火诸。也就是說先放的先取锦针,后放的后取,就如同行李過安檢的時候置蜀,先放進去的行李在另一端總是先出來奈搜,后放入的行李會在最后面出來。
4.iOS系統(tǒng)架構(gòu)
iOS的系統(tǒng)架構(gòu)分為四個層次:核心操作系統(tǒng)層(Core OS layer)盯荤、核心服務(wù)層(Core Services layer)馋吗、媒體層(Media layer)和可觸摸層(Cocoa Touch layer)
Core OS是最為核心的系統(tǒng)層,包括了內(nèi)存管理秋秤、文件系統(tǒng)耗美、硬件管理、電源管理航缀、安全管理等內(nèi)容商架,是iOS的核心操作系統(tǒng)。
Core Services包含了多種核心服務(wù)提供給 APP 使用芥玉,主要功能為 CoreFundation 和 Fundation 這兩個 framework蛇摸。
Media層主要包括了各種媒體文件的處理,通過它我們可以在應(yīng)用程序中使用各種媒體文件灿巧,進行音頻與視頻的錄制赶袄,圖形的繪制,以及制作基礎(chǔ)的動畫效果抠藕。
Cocoa Touch是可觸摸層饿肺,這一層為我們的應(yīng)用程序開發(fā)提供了各種有用的框架,并且大部分與用戶界面有關(guān)盾似,本質(zhì)上來說它負責用戶在iOS設(shè)備上的觸摸交互操作以及一些其他的關(guān)鍵功能比如多線程和通知等敬辣。
5.視圖控制器的生命周期
// ViewController.m
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
#pragma mark - 1. 類加載
+ (void)load {
}
#pragma mark - 2. 執(zhí)行類第一個方法前調(diào)用
+ (void)initialize {
}
#pragma mark - 3. nib文件解檔初始化
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [super initWithCoder:aDecoder];
}
#pragma mark - 4. nib文件解檔對象的個性化設(shè)置
- (void)awakeFromNib {
[super awakeFromNib];
}
#pragma mark - 5. 加載視圖
- (void)loadView {
[super loadView];
}
#pragma mark - 6. 視圖加載完畢,視圖個性化設(shè)置
- (void)viewDidLoad {
[super viewDidLoad];
}
#pragma mark - 7. 視圖即將顯示
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
#pragma mark - 8. 視圖即將為子視圖布局
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
}
#pragma mark - 9. 視圖已經(jīng)為子視圖布局完畢
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
}
#pragma mark - 10. 視圖已經(jīng)顯示完畢
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
#pragma mark - 11.視圖即將消失
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
}
#pragma mark - 12.視圖已經(jīng)消失
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
}
#pragma mark - 13.內(nèi)存不足時候會調(diào)用
-(void)didReceiveMemoryWarning{
}
@end
6.APP生命周期
(1)生命周期的5種狀態(tài)
- 未運行(Not running)
程序沒啟動 - 未激活(Inactive)
程序在前臺運行,不過沒有接收到事件溉跃。
一般每當應(yīng)用要從一個狀態(tài)切換到另一個不同的狀態(tài)時村刨,中途過渡會短暫停留在此狀態(tài)。唯一在此狀態(tài)停留時間比較長的情況是:當用戶鎖屏?xí)r撰茎,或者系統(tǒng)提示用戶去響應(yīng)某些(諸如電話來電嵌牺、有未讀短信等)事件的時候。 - 激活(Active)
程序在前臺運行而且接收到了事件龄糊。這也是前臺的一個正常的模式 - 后臺(Backgroud)
程序在后臺而且能執(zhí)行代碼逆粹,大多數(shù)程序進入這個狀態(tài)后會在在這個狀態(tài)上停留一會。時間到之后會進入掛起狀態(tài)(Suspended)炫惩。有的程序經(jīng)過特殊的請求后可以長期處于Backgroud狀態(tài) - 掛起(Suspended)
程序在后臺不能執(zhí)行代碼枯饿。系統(tǒng)會自動把程序變成這個狀態(tài)而且不會發(fā)出通知。當掛起時诡必,程序還是停留在內(nèi)存中的,當系統(tǒng)內(nèi)存低時搔扁,系統(tǒng)就把掛起的程序清除掉爸舒,為前臺程序提供更多的內(nèi)存。
(2)iOS13之前
點擊應(yīng)用程序圖標
1)程序入口:進入main
函數(shù)
2)通過UIApplicationMain
函數(shù)
3)初始化UIApplication
對象并且設(shè)置代理對象AppDelegate
4)程序完成加載:[AppDelegate application:didFinishLaunchingWithOptions:]
5)創(chuàng)建Window
窗口:UIWindow
6)程序被激活:[AppDelegate applicationDidBecomeActive:]
點擊Home鍵
1)程序取消激活狀態(tài):[AppDelegate applicationWillResignActive:]
2)程序進入后臺:[AppDelegate applicationDidEnterBackground:]
點擊應(yīng)用圖標
1)程序進入前臺:[AppDelegate applicationWillEnterForeground:]
2)程序被激活:[AppDelegate applicationDidBecomeActive:]
內(nèi)存警告
[AppDelegate applicationDidReceiveMemoryWarning]
將要終止
[AppDelegate applicationWillTerminate]
(3)iOS13之后
點擊應(yīng)用程序圖標
1)程序入口:進入main
函數(shù)
2)通過UIApplicationMain
函數(shù)
3)初始化UIApplication
對象并且設(shè)置代理對象AppDelegate
4)程序完成加載:[AppDelegate application:didFinishLaunchingWithOptions:]
5)進入場景對象調(diào)用:[SceneDelegate scene:willConnectToSession:options:]
方法
6)程序?qū)⒁M入場景:[SceneDelegate sceneWillEnterForeground:]
7)場景已經(jīng)激活:[SceneDelegate sceneDidBecomeActive:]
點擊Home鍵:
1)取消場景激活狀態(tài):[SceneDelegate sceneWillResignActive:]
2)程序進入后臺:[SceneDelegate sceneDidEnterBackground:]
點擊圖標
1)程序?qū)⒁M入前臺:[SceneDelegate sceneWillEnterForeground:]
2)程序已經(jīng)被激活:[SceneDelegate sceneDidBecomeActive:]
進入程序選擇界面
[SceneDelegate sceneWillResignActive:]
程序被殺死
[SceneDelegate sceneDidDisconnect:]
7.UIView的生命周期
純代碼
UIView創(chuàng)建為:[[UIView alloc] init];
1)initWithFrame:
2)init
3)layoutSubviews
純代碼
UIView創(chuàng)建為:[[UiView alloc] initWithFrame:[UIScreen mainScreen].bounds];
1)initWithFrame:
2)layoutSubviews
Xib
UIView創(chuàng)建為:NSArray *arr = [[NSBundle mainBundle] loadNibNamed:(@"XHView") owner:nil option:nil]; [arr lastObject];
1)initWithCoder:
2)awakeFromNib
3)layoutSubviews
8. UIApplication
UIApplication對象是應(yīng)用程序的象征稿蹲。
每一個應(yīng)用程序都有自己的UIApplication對象扭勉,而且是單例。
一個iOS程序啟動后創(chuàng)建的第一個對象就是UIApplication對象苛聘。
通過UIApplication *app = [UIApplication sharedApplication];可以獲得這個單例對象涂炎。
利用UIApplication對象能進行一些應(yīng)用級別的操作。
(1)創(chuàng)建
應(yīng)用程序的入口main.m
函數(shù)
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
第一個參數(shù):argc
系統(tǒng)或者用戶傳入的參數(shù)设哗。
第二個參數(shù):argv
系統(tǒng)或用戶傳入的實際參數(shù)唱捣。
第三個參數(shù) :nil
代表UIApplication類名或者子類名稱,nil
相當于 @"UIApplicaiton"
网梢。
第四個參數(shù) :代表UIApplicaiton的代理名稱NSStringFromClass([AppDelegate class]
相當于@"AppDelegate"
震缭。
(2)應(yīng)用級別的操作
設(shè)置應(yīng)用程序圖標右上角的紅色提醒數(shù)字
UIApplication *app = [UIApplication sharedApplication];
app.applicationIconBadgeNumber = 10;
// 創(chuàng)建通知對象
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
// 注冊用戶通知
[app registerUserNotificationSettings:setting];
設(shè)置聯(lián)網(wǎng)指示器的可見性
app.networkActivityIndicatorVisible= YES;
管理狀態(tài)欄
系統(tǒng)提供2種管理狀態(tài)欄的方式:
1)UIViewController管理(每一個UIViewController都可以擁有自己不同的狀態(tài)欄)
#pragma mark-設(shè)置狀態(tài)欄的樣式
-(UIStatusBarStyle)preferredStatusBarStyle
{
//設(shè)置為白色
//return UIStatusBarStyleLightContent;
//默認為黑色
return UIStatusBarStyleDefault;
}
#pragma mark-設(shè)置狀態(tài)欄是否隱藏(否)
-(BOOL)prefersStatusBarHidden
{
return NO;
}
2)UIApplication管理(一個應(yīng)用程序的狀態(tài)欄都由它統(tǒng)一管理)如果想利用UIApplication來管理狀態(tài)欄,首先得修改Info.plist的設(shè)置战虏,添加選中行拣宰,并設(shè)置為NO即可。
//通過sharedApplication獲取該程序的UIApplication對象
UIApplication *app=[UIApplication sharedApplication];
//設(shè)置狀態(tài)欄的樣式
//app.statusBarStyle=UIStatusBarStyleDefault;//默認(黑色)
//設(shè)置為白色+動畫效果
[app setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
//設(shè)置狀態(tài)欄是否隱藏
app.statusBarHidden=YES;
//設(shè)置狀態(tài)欄是否隱藏+動畫效果
[app setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];
openURL:
方法
UIApplication *app = [UIApplicationsharedApplication];
打電話 [app openURL:[NSURLURLWithString:@"tel://110"]];
發(fā)短信 [app openURL:[NSURLURLWithString:@"sms://10086"]];
發(fā)郵件 [app openURL:[NSURLURLWithString:@"mailto://xxcc@fox.com"]];
打開一個網(wǎng)頁資源 [app openURL:[NSURL URLWithString:@"http://www.baidu.com"]];
打開其他app程序 openURL方法烦感,可以打開其他APP巡社。
判斷程序運行狀態(tài)
//判斷程序運行狀態(tài)
/*
UIApplicationStateActive,
UIApplicationStateInactive,
UIApplicationStateBackground
*/
UIApplication *app = [UIApplication sharedApplication];
if(app.applicationState ==UIApplicationStateInactive){
NSLog(@"程序在運行狀態(tài)");
}
阻止屏幕變暗進入休眠狀態(tài)
//阻止屏幕變暗,慎重使用本功能手趣,因為非常耗電晌该。
UIApplication *app = [UIApplication sharedApplication];
app.idleTimerDisabled =YES;
9.性能測試
Profile
Instruments
Time Profiler
10.iOS的設(shè)計模式
http://www.reibang.com/p/f3b25ae273eb
http://www.reibang.com/p/40063d3e0807
http://www.reibang.com/p/c3bbe227d51c
http://www.reibang.com/p/eecee6055cde
11.MVC和MVVC設(shè)計模式
http://www.reibang.com/p/b6b6753c685f
http://www.reibang.com/p/d0408401c424
12.淺復(fù)制和深復(fù)制
http://www.reibang.com/p/46d76d01c05d
13. 繼承和類別區(qū)別
http://www.reibang.com/p/308e8b23ae52
14.類別和類擴展的區(qū)別
http://www.reibang.com/p/308e8b23ae52
15. 什么是KVO和KVC
http://www.reibang.com/p/4f7732babd0b
http://www.reibang.com/p/236a013cc244
16.代理的作用
http://www.reibang.com/p/f3b25ae273eb
17.oc是動態(tài)運行時語言是什么意思
主要是將數(shù)據(jù)類型的確定由編譯時,推遲到了運行時。
這個問題其實淺涉及到兩個概念气笙,運行時和多態(tài)次企。
http://www.reibang.com/p/308e8b23ae52多態(tài)
18.OC中協(xié)議和通知的區(qū)別
(1)代理 Delegate
- 代理是一種設(shè)計模式
- 在 iOS 中以
@protocol (協(xié)議)
形式實現(xiàn); - 傳遞方式 一對一潜圃;
- 協(xié)議中除了可以定義方法缸棵,還可以定義屬性;
- 一般聲明為
weak
以規(guī)避循環(huán)引用谭期;
優(yōu)勢
嚴格的語法堵第。所有的事件必須是在 delegate
協(xié)議中有清晰的定義,如果 delegate
中的一個方法沒有實現(xiàn)那么就會出現(xiàn)編譯警告/錯誤;
在一個應(yīng)用中的控制流程是可跟蹤的并且是可識別的隧出;
在一個控制器中可以定義多個不同的協(xié)議踏志,每個協(xié)議有不同的 delegate
;
沒有第三方對象要求保持/監(jiān)視通信過程胀瞪;
能夠接收調(diào)用的協(xié)議方法的返回值针余。這意味著 delegate
能夠提供反饋信息給委托方;
缺點 :
需要定義很多代碼:1.協(xié)議定義凄诞;2.委托對象的 delegate
屬性圆雁;3.在 delegate
本身中實現(xiàn) delegate
方法定義;
在釋放代理對象時帆谍,需要小心的將 delegate
改為 nil
伪朽。一旦設(shè)定失敗,那么調(diào)用釋放對象的方法將會出現(xiàn)內(nèi)存 crash汛蝙;
(2)通知 Notification
- 使用觀察者模式來實現(xiàn)的用于跨層傳遞消息的機制烈涮;
- 傳遞方式 一對多;
實現(xiàn)機制:在通知中心NSNotificationCenter
中維護著一個字典窖剑,key
是notificationName
坚洽,value
是一個數(shù)組,數(shù)組的每個元素里包含了觀察者和對應(yīng)的方法西土。
優(yōu)勢 :
不需要編寫多少代碼酪术,實現(xiàn)比較簡單;
對于一個發(fā)出的通知翠储,多個對象能夠做出反應(yīng)绘雁,即1對多的方式實現(xiàn)簡單;
被觀察者能夠傳遞 context
對象(dictionary)援所,context
對象攜帶了關(guān)于發(fā)送通知的自定義的信息庐舟;
缺點 :
在編譯期不會檢查通知是否能夠被觀察者正確的處理;
在釋放注冊的對象時住拭,需要在通知中心取消注冊(IOS9 之后可以不再手動remove)挪略;
在調(diào)試的時候應(yīng)用的工作以及控制過程難跟蹤历帚;
被觀察者和觀察者需要提前知道通知名稱、UserInfo dictionary keys杠娱。如果這些沒有在工作區(qū)間定義挽牢,那么會出現(xiàn)不同步的情況;
只把消息發(fā)送出去摊求,告知某些狀態(tài)的變化禽拔,但是并不關(guān)心誰想要知道這個。被觀察者也不能從觀察者獲得任何的反饋信息室叉。
(3)KVO (Key-Value Observing)
- 是ObjC對觀察者設(shè)計模式的實現(xiàn)睹栖;
- 傳遞方式支持 一對多;
實現(xiàn)機制:通過一種稱作isa-swizzling
的機制實現(xiàn)的茧痕,這個機制會在被觀察對象的屬性被監(jiān)聽時修改對象的isa指針野来,讓指針指向一個中間類而非對象自身的類。
優(yōu)勢 :
能夠提供一種簡單的方法實現(xiàn)兩個對象間的同步踪旷。例如:model 和 view 之間同步曼氛;
能夠?qū)Ψ俏覀儎?chuàng)建的對象,即內(nèi)部對象的狀態(tài)改變作出響應(yīng)令野,而且不需要改變內(nèi)部對象的實現(xiàn)舀患;
能夠提供觀察的屬性的最新值以及先前值;
用 key paths 來觀察屬性彩掐,因此也可以觀察嵌套對象;
缺點 :
我們觀察的屬性必須使用 strings 來定義灰追。因此在編譯器不會出現(xiàn)警告以及檢查堵幽;
對屬性重構(gòu)將導(dǎo)致我們的觀察代碼不再可用;
對象正在觀察多個值弹澎,需要復(fù)雜的“IF”語句要求朴下。因為所有的觀察代碼通過一個方法來指向;
當釋放觀察者時不需要移除觀察者
19.iOS響應(yīng)鏈
http://www.reibang.com/p/5212c141d57e
20.frame
和 bounds
不同
view.frame = CGRectMake(CGFloat x, CGFloat y, CGFloat
width, CGFloat height)
view.bounds = CGRectMake(CGFloat x, CGFloat y,
CGFloat width, CGFloat height)
兩者的共同點是后面兩個參數(shù)都是設(shè)置控件的大小苦蒿,區(qū)別是前兩個參數(shù)殴胧,對于 frame
來說,CGFloat x佩迟、 CGFloat y
兩個參數(shù)是 view
相對于父視圖的位置团滥,bounds
是 view
上面的子視圖在 view
上面的起始位置。