第八課:html
一、協議git
另外一種安全處理id類型的方式如:id <MyProtocol> objgithub
a.聲明segmentfault
//協議通常放於.h文件中或者在類的.h文件中 @protocol Foo <Xyzzy, NSObject>//<>中的內容表示還需實現自哪些協議,全部協議的根協議通常都是NSObject - (void)someMethod;//默認爲必須實現的方法 @optional//可選方法聲明 - (void)methodWithArgument:(BOOL)argument; @required @property (readonly) int readonlyProperty; //只有getter在協議中 @property NSString *readwriteProperty; //getter與setter都在協議中 - (int)methodThatReturnsSomething; @end
b.在類中實現協議安全
#import 「Foo.h」 @interface MyClass : NSObject <Foo> //(do not have to declare Foo’s methods again here, it’s implicit that you implement it) @end //或者私有實現 @interface MyClass() <Foo> @end @implementation MyClass //@required methods here! @end
c.用途多線程
①委託框架
②數據源dom
//UI與controller盲通訊的方式 @property (nonatomic, weak) id <UISomeObjectDelegate> delegate; @property (nonatomic, weak) id <UISomeObjectDataSource> dataSource;
③動畫async
二、Block(來源於API文檔)ide
實際上爲一段代碼塊,相似於C語言中的函數指針
a.聲明
int multiplier = 7; int (^myBlock)(int) = ^(int num) { return num * multiplier; }; //int 爲block返回值 //^表示爲此爲代碼塊 //myBlock爲此代碼塊名 //int 爲參數類型 //等號右邊爲block實現
block可使用和他的同一範圍內聲明的變量,使用block與使用C函數相似
int multiplier = 7; int (^myBlock)(int) = ^(int num) { return num * multiplier; }; printf("%d", myBlock(3)); // prints "21"
b.直接使用block
block能夠省略block聲明直接使用
char *myCharacters[3] = { "TomJohn", "George", "Charles Condomine" }; //直接使用block做爲參數 qsort_b(myCharacters, 3, sizeof(char *), ^(const void *l, const void *r) { char *left = *(char **)l; char *right = *(char **)r; return strncmp(left, right, 1); }); // myCharacters is now { "Charles Condomine", "George", "TomJohn" }
c.Cocoa中使用block
NSArray *stringsArray = @[ @"string 1", @"String 21", @"string 12", @"String 11", @"String 02" ]; static NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch | NSNumericSearch | NSWidthInsensitiveSearch | NSForcedOrderingSearch; NSLocale *currentLocale = [NSLocale currentLocale]; //比較器爲代碼塊 NSComparator finderSortBlock = ^(id string1, id string2) { NSRange string1Range = NSMakeRange(0, [string1 length]); return [string1 compare:string2 options:comparisonOptions range:string1Range locale:currentLocale]; }; NSArray *finderSortArray = [stringsArray sortedArrayUsingComparator:finderSortBlock]; NSLog(@"finderSortArray: %@", finderSortArray); /* Output: finderSortArray: ( "string 1", "String 02", "String 11", "string 12", "String 21" ) */
d.__block變量
首先看簡單的例子
//直接使用變量 int x = 123; void (^printXAndY)(int) = ^(int y) { printf("%d %d\n", x, y); }; printXAndY(456); // prints: 123 456 //不能夠直接更改變量,此處變量對block來講爲只讀 int x = 123; void (^printXAndY)(int) = ^(int y) { x = x + y; // error printf("%d %d\n", x, y); };
解決方法,引入__block變量
__block int x = 123; // x lives in block storage void (^printXAndY)(int) = ^(int y) { x = x + y; printf("%d %d\n", x, y); }; printXAndY(456); // prints: 579 456 // x is now 579
e.各類類型的變量在block中的使用
對於普通局部變量,在block聲明時保存其值,以後普通局部變量的改變對block不可見
//注意block的調用時機 extern NSInteger CounterGlobal;//block對全局變量有讀寫權限 static NSInteger CounterStatic;//靜態變量 { NSInteger localCounter = 42;//普通本地變量 __block char localCharacter;//__block本地變量 void (^aBlock)(void) = ^(void) { ++CounterGlobal; ++CounterStatic; CounterGlobal = localCounter; // localCounter fixed at block creation localCharacter = 'a'; // sets localCharacter in enclosing scope }; ++localCounter; // unseen by the block,對block不可見,block的值認爲42 localCharacter = 'b'; aBlock(); // execute the block // localCharacter now 'a' }
f.對象在block中的使用
dispatch_async(queue, ^{ /* block中訪問實例變量,instanceVariable爲block所在類的實例變量,此時直接訪問了實例變量,所以須要對包含它的對象(self)保留 */ doSomethingWithObject(_instanceVariable); }); id localVariable = _instanceVariable; dispatch_async(queue, ^{ /* 在本地建立了指向實例變量的引用,所以須要保留localVariable而不是self */ doSomethingWithObject(localVariable); });
g.使用typedef聲明block
typedef float (^MyBlockType)(float, float); MyBlockType myFirstBlock = // ... ; MyBlockType mySecondBlock = // ... ;
h.Memory Cycles
//block中引用self,因此有強指針指向self,而block又在self中定義,因此self又有強指針指向block [self.myBlocks addObject:^ { [self doSomething]; }];
解決方法
__weak MyClass *weakSelf = self; //從新聲明爲弱引用 [self.myBlocks addObject:^ { [weakSelf doSomething]; }];
i.用途
枚舉,動畫,排序,通知(Notification),Error handlers,Completion handlers (錯誤與完成事件的處理,能夠理解爲回調函數),多線程等
三、動畫(Animation)
a.動畫的種類
Animating views :視圖動畫,包括移動、縮放、淡入淡出、旋轉等
Animation of View Controller transitions:視圖控制器動畫,視圖的切換等
Core Animation:核心動畫框架
本節課只涉及視圖動畫
b.爲視圖添加動畫的三種方法
①經過設置視圖屬性
frame
transform (translation, rotation and scale)
alpha (opacity)
值會當即改變,但動畫效果會延時
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;//適用於常規動畫設置 //example [UIView animateWithDuration:3.0 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{ myView.alpha = 0.0; } completion:^(BOOL fin) { if (fin) [myView removeFromSuperview]; }];//視圖在3秒內從父視圖淡出,完成動畫後並移除本身 + (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;//適用於轉場動畫設置,好比卡牌的翻轉 + (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion;//適用於切換視圖動畫
//UIViewAnimationOptions //常規動畫屬性設置(能夠同時選擇多個進行設置) UIViewAnimationOptionLayoutSubviews //父視圖變化時自動更新子視圖約束@see:http://segmentfault.com/q/1010000002872390 UIViewAnimationOptionAllowUserInteraction //動畫時響應用戶事件,如 touch等 UIViewAnimationOptionBeginFromCurrentState //從當前狀態開始動畫,好比此時有動畫正在改變屬性 UIViewAnimationOptionRepeat //無限制重複動畫 UIViewAnimationOptionAutoreverse //執行動畫迴路(動畫運行到結束點後仍然以動畫方式回到初始點),前提是設置動畫無限重複 UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套動畫時間設置 UIViewAnimationOptionOverrideInheritedCurve //忽略嵌套動畫速度設置 UIViewAnimationOptionAllowAnimatedContent //動畫過程當中重繪視圖(注意僅僅適用於轉場動畫) UIViewAnimationOptionShowHideTransitionViews //視圖切換時直接隱藏舊視圖、顯示新視圖,而不是將舊視圖從父視圖移除(僅僅適用於轉場動畫) UIViewAnimationOptionOverrideInheritedOptions //不繼承父動畫設置或動畫類型 //動畫速度控制(可從其中選擇一個設置) UIViewAnimationOptionCurveEaseInOut //動畫先緩慢,而後逐漸加速 UIViewAnimationOptionCurveEaseIn //動畫逐漸變慢 UIViewAnimationOptionCurveEaseOut //動畫逐漸加速 UIViewAnimationOptionCurveLinear //動畫勻速執行,默認值 //轉場類型(僅適用於轉場動畫設置,能夠從中選擇一個進行設置,基本動畫、關鍵幀動畫不須要設置) UIViewAnimationOptionTransitionNone //沒有轉場動畫效果 UIViewAnimationOptionTransitionFlipFromLeft //從左側翻轉效果 UIViewAnimationOptionTransitionFlipFromRight //從右側翻轉效果 UIViewAnimationOptionTransitionCurlUp //向後翻頁的動畫過渡效果 UIViewAnimationOptionTransitionCurlDown //向前翻頁的動畫過渡效果 UIViewAnimationOptionTransitionCrossDissolve //舊視圖溶解消失顯示下一個新視圖的效果 UIViewAnimationOptionTransitionFlipFromTop //從上方翻轉效果 UIViewAnimationOptionTransitionFlipFromBottom //從底部翻轉效果
②Dynamic Animator :動力動畫
實現步驟:a.建立一個UIDynamicAnimator
b.向UIDynamicAnimator添加UIDynamicBehaviors(gravity, collisions, etc.)
c.向UIDynamicAnimator添加UIDynamicItems(usually UIViews)
d.動畫自動運行
//Create a UIDynamicAnimator UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:aView]; //Create and add UIDynamicBehaviors UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init]; [animator addBehavior:gravity]; UICollisionBehavior *collider = [[UICollisionBehavior alloc] init]; [animator addBehavior:collider]; //Add UIDynamicItems to a UIDynamicBehavior id <UIDynamicItem> item1 = ...; id <UIDynamicItem> item2 = ...; [gravity addItem:item1]; [collider addItem:item1]; [gravity addItem:item2];
//UIDynamicItem 協議 @protocol UIDynamicItem @property (readonly) CGRect bounds; @property (readwrite) CGPoint center; @property (readwrite) CGAffineTransform transform; @end //通常UIView便可做爲Item,天生實現了UIDynamic協議 //以上屬性通常有動畫運行時的animator來改變,若須要主動改變,須要調用 - (void)updateItemUsingCurrentState:(id <UIDynamicItem>)item;
UIDynamicBehaviors
//UIGravityBehavior @property CGFloat angle;//重力方向,默認向下 @property CGFloat magnitude; // 1.0 is 1000 points/s/s //UICollisionBehavior 碰撞 @property UICollisionBehaviorMode collisionMode; // Items,Boundaries,Everything (default) - (void)addBoundaryWithIdentifier:(NSString *)identifier forPath:(UIBezierPath *)path; //用UIBezierPath自定義碰撞邊界 @property BOOL translatesReferenceBoundsIntoBoundary;//參考視圖(動力動畫的頂級視圖)做爲碰撞邊界 //UIAttachmentBehavior 吸附行爲 - (instancetype)initWithItem:(id <UIDynamicItem>)item attachedToAnchor:(CGPoint)anchor;//以點做爲吸附 - (instancetype)initWithItem:(id <UIDynamicItem>)i1 attachedToItem:(id <UIDynamicItem>)i2;//以動力項做爲吸附,兩個動力項的吸附 - (instancetype)initWithItem:(id <UIDynamicItem>)item offsetFromCenter:(CGPoint)offset ... //偏移中心的吸附 @property (readwrite) CGFloat length; // 吸附的長度 @property (readwrite) CGPoint anchorPoint; // 吸附點 @property (readwrite, nonatomic) CGFloat damping; // 錨點移動時的阻尼 @property (readwrite, nonatomic) CGFloat frequency; // 錨點移動時的頻率 //UISnapBehavior 捕捉行爲 - (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:(CGPoint)point; @property CGFloat damping;.//移動到錨點時振動的阻尼 //UIPushBehavior 推進行爲 @property UIPushBehaviorMode mode; // Continuous or Instantaneous @property CGVector pushDirection; @property CGFloat magnitude/angle; // magnitude 1.0 moves a 100x100 view at 100 pts/s/s //UIDynamicItemBehavior 動力項行爲,應用於全部Items @property (readwrite, nonatomic) CGFloat elasticity; // 彈力,[0.1] @property (readwrite, nonatomic) CGFloat friction; //摩擦力,0表示無摩擦力 @property (readwrite, nonatomic) CGFloat density; // 密度,默認爲1 @property (readwrite, nonatomic) CGFloat resistance; //線性阻力系數0--CGFLOAT_MAX @property (readwrite, nonatomic) CGFloat angularResistance; //角度阻力系數0--CGFLOAT_MAX @property (readwrite, nonatomic) BOOL allowsRotation; //是否容許旋轉 - (CGPoint)linearVelocityForItem:(id <UIDynamicItem>)item;//獲取Item速度 - (CGFloat)angularVelocityForItem:(id <UIDynamicItem>)item;//獲取Item角速度
建立UIDynamicBehavior子類實現自定義行爲
- (void)addChildBehavior:(UIDynamicBehavior *)behavior;//將其餘行爲添加到自定義行爲中 @property UIDynamicAnimator *dynamicAnimator;//獲取當前行爲所在的Animator - (void)willMoveToAnimator:(UIDynamicAnimator *)animator;//行爲加入到方法或者移除時(此時參數爲nil)會調用 @property (copy) void (^action)(void);//每當行爲發生時總會執行此block,注意調用比較頻繁的效率問題
四、demo
Dropit:https://github.com/NSLogMeng/Stanford_iOS7_Study/commit/515b76c7ed6e74a7e30108efe6d4c833f33a6e0c
課程視頻地址:網易公開課:http://open.163.com/movie/2014/1/D/L/M9H7S9F1H_M9H80D0DL.html
或者iTunes U搜索standford課程