1M_V_C
模型類:應該使用獨立於表現層的方式封裝數據,應該只引用模型類不應該引用視圖或者控制器類,模型類是可變或不可變:
不可變的好處是節約時間和內存,在沒有鎖定的情況下是線程安全的,應該儘量使用不可變的
視圖類:負責與用戶交互,提供信息並且接受用戶事件,但是自己不處理,交由控制器處理,除了父視圖與子視圖外,不應該引用其他視圖或控制器
控制器:實現大部分應用程序的特定邏輯,在模型類與視圖類之間起協調作用,訪問全局對象時應該創建單例,
2委託-策略模式
一般而言對象不保留他們的委託,應該將委託聲明爲weak,因爲但大多數情況是,對象的委託就是其控制器,而控制器總是保留的,如果對象想在保留委託就會形成循環引用,內存泄露
3命令模式
命令模式就是將請求封裝成一個對象,與直接調用不同,必須把方法調用打包放進一個對象,之後可能調用,可以提高靈活性,允許請求排隊,重定向,記錄和序列化
1使用方法簽名和調用
NSinvocation將目標,選擇器,方法簽名和所有的參數放進一個對象裏,可以先存儲以備調用,當NSinvocation被調用時,他會發消息,OC運行時會找到正確的方法來執行
方法實現IMP是一個紙箱如下簽名的C函數的函數指針
id function(id self ,SEL _cmd..)
目標是接收消息的對象,選擇器則是被髮送的消息,就是方法的名稱,如[nsstring length]和[nsdata length]雖然實現發放不一致但是他的選擇器確實相同的
還包含一個方法簽名(NSMethodSigature),封裝了一個方法的返回類型和參數類型,只有返回類型和參數類型
NSMethodSigature * sig =[NSMethodSigature sigarureWithOBJCTypes:"@@:*"];
第一個@表明返回值是一個id 接下來@:表明方法接受一個id和SEL 最後的*表明第一個“真實”參數是一個字符串char*
有了選擇器和簽名,可以使用一個目標和參數值將他們聯繫起來構建一個NSinvocation 包含傳遞信息的一切 以下代碼可以在[set addobject:stuff]調用
NSMutableSet *set =NSMutableSet set];
NSString * str = @"stuff";
SEL selector = @Selector(addObject:);
NSMethodSigature * sig = [set methodSigatureForSelector:selector];
Nsinvocation *invocation =[Nsinvocation invocationWithSigature:sig];
[invocation setTarget:set];
[invocation setSelector:selector];
[invocation setArgument:&str atIindex:2];//添加多個參數
[invocation invoke];
第一個參數至於2 因爲0與1位置分別是target和selector 用處:
1 聲明@dynamic動態屬性 ,根據以下方法可以動態生成setter,getter方法
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
- (void)forwardInvocation:(NSInvocation *)anInvocation;
2消息轉發不受空間限制,只要獲取到方法簽名即可調用,在撤銷操作時可調用
NSMethodSignature *sig = [selfmethodSignatureForSelector:@selector(addAlbum:atIndex:)];
NSInvocation *undoAction = [NSInvocationinvocationWithMethodSignature:sig];
[undoAction setTarget:self];
[undoActionsetSelector:@selector(addAlbum:atIndex:)];
[undoActionsetArgument:&deletedAlbumatIndex:2];
[undoActionsetArgument:¤tAlbumIndexatIndex:3];
[undoActionretainArguments];
// 3
[undoStackaddObject:undoAction];
將NSInvocation放入數組中逐個調用可實現效果
4觀察者模式(kvo,通知)
5單例模式