object - c 語言基礎 進階筆記 隨筆筆記


重點知識
Engadget(癮科技)
StackOverFlow(棧溢出)
Code4Apprespon
魏先宇的程序人生
第一週
快捷鍵: Alt+上方向鍵 跳到最上面  Alt+下方向鍵 跳到最下面
        Alt+左方向鍵 跳到最左面   Alt+右方向鍵 跳到最右面
        Alt+shift+方向鍵  能夠批量複製內容,在按方向鍵能夠刪除行
        command+鼠標  縱向複製內容
userInteractionEnabled  控件的交互性;
類的三大特性 :工程名:首字母必定要大寫,若是名字包含多個單詞,則每一個單詞的首字母都要大寫。
方法名:  命名規則和屬性名(變量名)相同,第一個單詞的首字母小寫,之後的每一個單詞的首字母都要大寫。

#import<>  #import關鍵字,導入工具   <> 表明導入是系統的工具類的頭文件    「」 表明導入的是本身的類的頭文件

@"" 表明OC中的字符串

邏輯運算 &(與) |(或) !(非)
&& 而且   || 或者   ! 非 !YES = NO  !NO = YES

對於c的函數,非void類型都要使用return return後面的代碼都再也不執行
Control reaches end of non-void function
控制到達了非空方法的末尾    表示此方法須要有返回值。必須使用return。


.h  header  頭文件   做用只是作類的聲明,作屬性的聲明,不作賦值,作方法的聲明,不作實現。  方法分爲-實例方法和+類方法。 在類方法中是不容許訪問屬性(instance variable 實例變量)
.m  main      主文件  實現文件  做用:.h不作了,我來作。 方法的實現和屬性的賦值(屬性的賦值是放在方法中完成)。
非ARC下)對於一個方法,在.h未聲明,可是在.m中已經實現,則仍然能夠調用。

執行類中的方法: OC調用方法都使用 [ ]
+(eat)   1 導入People頭文件
2 調用+eat方法    [類名  類方法的方法名];
-(eat) 1 導入頭文件     
2 建立對象  People *p = [People alloc];
3 對象調用實例方法  [對象名 方法名];

Log 日誌     %d  %lld % i  %f
 %@ 對象類型(指針類型)
 NSLog(@"=====%@",p2);   =====<People: 0x100200960>
  %p 輸出指針保存的內存地址 pointer 指針   
 NSLog(@"=====%p",p2);   =====0x1002063d0

聲明多個參數的方法:
- (int)sum:(int)value1 withSecond:(int)value2;
//方法類型 (返回值類型)方法名部分1(參數1類型)參數1名 方法名部分2(參數2類型)參數2名....


屬性用來使用 (設置屬性值,得到屬性值)
案例:設置一我的的年齡,而且設置以後得到設置後的年齡值。
只能經過方法訪問屬性值。
對於對象打點調用屬性,所調用的set和get的方法的方法名是固定的:age屬性: setAge    age
set 和get方法
————————
對象調用set和get方法
————————
set 和get方法
對象名.屬性名(代替調用set和get的方法的一種簡易寫方法)
————————
@property+@synthesize(屬性的聲明和實現,代替屬性set和get方法)
對象名.屬性名
————————
同種類型的屬性聲明能夠寫在一塊兒,用逗號分隔。
@property float height,weight;
@property int age;
@property bool sex;
@synthesize height,age,sex,weight;
若是類中存在屬性的set和get方法,則對屬性設置值和得到值時,可使用兩種方式:
1 對象調用set和get方法
2 對象打點調用屬性 對象名.屬性名
對象打點調用屬性的本質調用屬性的set和get方法。

在.h中聲明的屬性變量,在.m中的任何一個方法中均可以使用(+方法除外),這個屬性變量通常叫作 全局變量。
全局變量(屬性) 局部變量(某個方法中定義的變量)
局部變量會覆蓋全局變量(變量名相同)

NSString  字符串類    聲明變量 *
默認是nil ,在控制檯上輸出的是(null),指針指向的地址是0x0.
nil是一個對象指針爲空,Nil是一個類指針爲空,NULL是基本數據類型爲空。
NSString 類型 共有的只有NSString,不共有*。
@property NSString *name,*name1;

內存管理  ARC  Automatic Reference Counting
                                    自動            引用            計數
Xcode 5.x 默認建立工程 支持ARC
關閉ARC: Building Setting ---搜索:auto---Objective-C 把ARC改爲NO  /  gar 把ARC改爲NO
(非ARC下)在.m中已經實現但在.h中未聲明的方法仍然能夠調用。

繼承的特性:子類繼承父類,會繼承父類 全部的 屬性和方法。

self 本類的對象    super 父類的對象


重寫的init方法。
目的:把屬性的初始化工做直接寫在了init方法中。
自定義的initWithXX方法。
目的:能夠對對象的屬性進行賦值

強制類型轉換 :       (轉換後的類型)須要轉換的變量
float a = 3.14;    int b  = (int)a
強制類型轉換隻能轉換指針類型,不能轉換它的對象類型

People *p = [[People alloc] init];
p完成初始化以後再賦給p,那麼這時的指針指向的對象就已是完成初始化以後的對象。
init方法是完成系統最基本的初始化工做,好比優化內存等。
重寫的init方法就能替代多參完成屬性賦值的初始化操做。
+alloc  -init  是NSObject的方法    People : NSObject

id OC中的弱類型 強 能夠接收任意類型,通常接收對象類型(*)
alloc和init方法返回值類型都是id的緣由是這裏返回值不能是固定的類型(People*),任何NSObject的子類People調用alloc或init方法時都返回該類的對象,而且使用People類的指針接收。

- (id)init
{
self = [super init];
若是父類初始化成功,則完成 本身的初始化工做。
    if (self)  //    if (self != nil)
    {
 //      initialize code
        age = 18;
        sex = YES;
        [self eat];
    }
  //  最後返回的self ,不只完成了父類的初始化工做,並且也完成本身的初始化工做。
    return self;
}

設置本身飛機的移動
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    //得到touch事件
    UITouch* touch = [touches anyObject];
    //根據touch事件得到點的座標
    CGPoint point = [touch locationInView:self.window];
    if (CGRectContainsPoint(myPlane.frame, point))
    {
        myPlane.center = point;
    }
}

讓鍵盤下去的方法:
1.[_loginPassWordTxt addTarget:self action:@selector(keyBoardLeave) forControlEvents:UIControlEventEditingDidEndOnExit]; 下面實現 keyBoLeave 方法時能夠什麼都不寫
2.-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //當前view結束編輯
    [self.view endEditing:YES];
    //當textField失去焦點的時候,鍵盤也會下去
    3.//[_userNameTxt resignFirstResponder];
}


局部變量的生命週期 從聲明開始到方法的結束

for循環語句中    能夠定義 static  靜態變量  它只會被初始化一次    會保存在內存裏面的 靜態存儲區

i++ i是先使用,後++    ++i  i是先++,後使用


控件 窗口小部件(組件)  手機軟件中的按鈕,標籤等,,
UI  UserInterface   用戶接口界面
1.標籤 顯示文字   2.按鈕  點擊用於觸發事件      
3. 文本框  輸入文字        

AppDelegate 應用程序代理類    入口類
入口類中的didFinishLaunching 入口方法 至關於代替了main方法。

CGRect (數據類型)  結構體
typedef(類型定義)    struct   CGRect   CGRect;
typedef  a   b    用b代替a

若是想肯定一個控件的位置,要麼使用frame,要麼使用bounds+center,僅僅設置bounds,那麼默認center爲(0,0),這樣只會顯示此控件的1/4(右下半)。

device  真機調試
3.5 inch iPhone4 4s     4 inch iPhone 5 5c 5s SE  4.7 inch iPhone 6 6s  5.5 inch iPhone 6s  6sp
ipad1,2  1024 * 768   9.7寸
ipad3 ,4  2048 * 1536
ipad mini 1024 * 768    7.9寸
ipad mini (retina)2048 * 1536
ipad air (ipad 5) 2048 * 1536 9.7寸

ipad模擬器:      1024*768
iphone 3.5inch   320* 480
iphone 4inch      320*568
iphone 4.7inch   375*667php

iphone 5.5inch   540*960html


第二週

Lab.textAlignment = NSTextAlignmentCenter;  設置字體居中
TextField.placeholder = @"請輸入密碼";   設置隱藏編輯字符
TextField.secureTextEntry = YES;   設置是否安全鍵入
TextField.borderStyle = UITextBorderStyleRoundedRect;  設置邊框樣式  border  邊角
TextField.clearButtonMode = UITextFieldViewModeAlways;      設置清除文本框
[t addTarget:self action:@selector(XX) forControlEvents:UIControlEventEditingDidEndOnExit];    設置return鍵取消鍵盤
是否容許剪切    earth.clipsToBounds=YES;
這個值設置長寬高的一半  earth.layer.cornerRadius=20;

字符串判斷是否相等  isEqualToString

去掉字符串中的空格和空白
str = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]

返回參數字符串在原字符串中的位置和長度
//返回值是NSRange,相似於CGRect,CGPoint
//NSRange有兩個屬性,location,length
//location,參數字符串的第一個字符在原字符串中的位置
//length,參數字符串的長度
//若是原字符串不包含參數字符串,返回的NSRange的location的值爲NSNotFound
if ([urlString rangeOfString:@"code"].location == NSNotFound) {};

//substringToIndex,截取字符串,從0開始,到index結束
//substringFromIndex,截取字符串,從index開始,到末尾結束
//substringWithRange,截取字符串,從location開始,長度爲length
 textView.text = [resultString substringToIndex:10];

#define  宏定義    分爲 常量宏  函數宏


IBAction 綁定方法  IBOutlet  關鍵字 關聯對象   (xib中在.h文件中寫的)

若是xib文件被修改後 需手動加載xib文件 調用 [ ]initWithNibName:@「」……

獲取window的方式
1. UIWindow *window = [UIApplication sharedApplication].keyWindow;
2. AppDelegate * app =[UIApplication sharedApplication].delegate;
UIWindow *window = app.window;
3. NSArray *array = [UIApplication sharedApplication].Windows;
UIWindow *window = [array objectAtIndex : 0 ];
部分可用 self.view.window

字符串拼接來找圖片的圖片名  (格式化字符串)
NSString* imageName = [NSString stringWithFormat:@"Fire%d.gif",i];
根據圖片名找圖片放到fire的imageView上  
fire.image = [UIImage imageNamed:imageName];

讓定時器方法再也不等待第一個時間差   [Timer fire];
暫時關閉定時器  [timer setFireDate:[NSDate distantFuture]];
再開啓定時器   [timer setFireDate:[NSDate distantPast]];
永久關閉定時器  [timer invalidate];  timer = nil;

輸出一個對象的CGRect , CGPoint ,CGSize :
NSLog(@"%@",NSStringFromCGRect(CGRect rect));
NSLog(@"%@",NSStringFromCGPoint(CGPoint point));
NSLog(@"%@",NSStringFromCGSize(CGSize size));

//輸出字節數
    NSLog(@"int---%lu",sizeof(int));
    NSLog(@"long---%lu",sizeof(long));


第三週

開闢線程的兩種方法
//開闢分線程的時候,綁定一個方法,讓這個方法在分線程裏面執行.
[NSThread detachNewThreadSelector:@selector(new) toTarget:self withObject:nil];
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(new) object:nil];     經過alloc 方法開闢線程  須要去調用start方法 [thread start];

解決多個線程同時訪問一個數據(類比 多個賣票點同時賣一張火車票),
1.NSLock 加線程鎖,  
//    _lock = [[NSLock alloc] init];
//    [_lock lock];
    線程隊列執行
//    [_lock unlock];
2,線程同步塊  @synchronized(self)

分線程中不能開啓 Timer
分線程中不會執行UI的更新,要回到主線程去更新  [self performSelectorOnMainThread:(SEL) withObject:(id) waitUntilDone:(BOOL)];
waitUntilDone:   爲yes 讓分線程等待,直接去主線程中執行,執行完畢後繼續執行當前的分線程
爲NO, 分線程執行結束再去執行主線程
當前線程休眠  [NSThread sleepForTimeInterval:(NSTimeInterval)];
[Thread MainThread];       [Thread currentThread];    //判斷當前線程是否爲主線程,返回值爲 BOOL類型    [NSThread isMainThread];

12.31號 :// 獲取URL地址上的data 方法 是一個同步的方法
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://b.hiphotos.baidu.com/image/pic/item/e4dde71190ef76c666af095f9e16fdfaaf516741.jpg"]];

//perform 執行, 在主線程中執行一個方法,能夠傳一個參數給這個方法
// 拿到數據以後 回到主線程刷新UI  分線程不能刷新UI
    [self performSelectorOnMainThread:@selector(setImageViev:) withObject:data waitUntilDone:YES];

3,操做隊列:
//用操做隊列能夠解決線程同步的問題,若是有多個操做的話,每一個操做隨機先執行,執行完一個操做以後纔去執行另一個操做,不會出現一個數據同時被多個操做訪問的狀況.
    
    // 建立一個操做 綁定相應的方法,當把操做添加到操做隊列中時 操做綁定的方法就會自動執行了
     // 建立一個操做隊列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
     // 1,系統提供的操做
    // 調用操做
    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomeThing) object:nil];
     // 把操做添加到操做隊列中
    [queue addOperation:operation1];


設置導航欄標題
第一種
self.title = @"setting";
第二種
self.navigationItem.title = @"1111";
第三種    
UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
lab.text = @"111222";
lab.backgroundColor = [UIColor redColor];
self.navigationItem.titleView = lab;

設置導航欄右邊按鈕選項
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(buttonClick:)];
self.navigationItem.rightBarButtonItems = rightButton ;

跳轉到下一個界面
1. SecondViewController *secondVC = [[SecondViewController alloc] init];
  [self.navigationController pushViewController:secondVC animated:YES];
2.模態彈出
 SecondViewController *secondVC = [[SecondViewController alloc] init];
[self.navigationController presentViewController:secondVC animated:YES completion:nil];
(若是使用模態彈出,此時沒有導航欄且ViewController 不會被加載到導航控制器中,那麼就不能使用pop方法)                  若想返回上一個界面,要使用
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
    //模態彈出的樣式( 非全屏 formSheet,pageSheet)
    vc.modalPresentationStyle = UIModalPresentationFormSheet;
        //模態彈出的動畫方式
    vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;

返回到上一個界面
[self.navigationController popViewControllerAnimated:YES];
返回到根視圖界面
[self.navigationController popToRootViewControllerAnimated:YES];
返回到指定視圖界面
(獲取導航器中的全部導航控制器)     NSArray *array = self.navigationController.viewControllers;
[self.navigationController popToViewController:[array objectAtIndex:0] animated:YES];

在一個數組中插入數組
NSMutableArray *array1 = [NSMutableArray arrayWithObjects: @"one", @"two", @"three", @"four", nil];
NSArray *newAdditions = [NSArray arrayWithObjects: @"a", @"b", nil];
NSMutableIndexSet *indexes = [NSMutableIndexSet indexSetWithIndex:1];[indexes addIndex:3];
//  indexes   1  3
[array1 insertObjects:newAdditions atIndexes:indexes];
NSLog(@"array: %@", array)
// Output: array: (one, a, two, b, three, four)

 替換多個索引值的對象
(NSIndexSet *) 索引
[arr replaceObjectsAtIndexes:(NSIndexSet *) withObjects:(NSArray *)];


從第二界面回到第一界面時 此時viewdidload方法再也不執行,由於視圖已經加載過了
此時須要重寫viewWillAppear(視圖將要顯示)
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
     NSLog(@"從第二個頁面獲得的內容  %@",self.fromSecondText);
//    把第二界面的內容賦值給text1
    text1.text = self.fromSecondText;
}

判斷從數組中取的對象是不是( )類型的對象用 iskindOfClass

ScrollView.contentSize (容量大小)
設置水平豎直方向的標示符
scrollView.showsHorizontalScrollIndicator = YES;
scrollView.showsVerticalScrollIndicator = YES;
設置是否能夠分頁
scrollView.pagingEnabled = YES;
設置是否回彈
scrollView.bounces = YES;
設置偏移量  (向左爲正  向右爲負)
scrollView.contentOffset = CGPointMake(30, 0);
設置拖動過程當中水平或者垂直方向可否被鎖定
scrollView.directionalLockEnabled = YES;
設置 scrollView 四個邊界的預留空白區域
scrollView.contentInset = UIEdgeInsetsMake(40, 40, 0, 0);
ScrollView中實現圖片的縮放
設置它的最大放大比例(長和寬)
  _scrollView.maximumZoomScale = 4;
  _scrollView.minimumZoomScale = 0.25;
 返回須要縮放的 View,這個 View 必須是 scrollview 的子 View,實現了這個方法,scrollview 就能夠實現縮放了。  若是使用了 scrollView 的縮放功能,就不能再用它的滑動效果,不然會亂。
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return _imageView;
}
當 scrollView 已經縮放時的回調
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
  //_imageView.center = self.view.center;(縮小的時候能夠用)
    if (scrollView.zoomScale<1)
    {
        float width = _scrollView.frame.size.width*(1-scrollView.zoomScale)/2;
        float height = _scrollView.frame.size.height*(1-scrollView.zoomScale)/2;
        scrollView.contentInset = UIEdgeInsetsMake(height, width, 0, 0);
    }
}


PageControl.numberOfPages  設置頁數(幾個點)
PageControl.currentPage  當前的頁數

系統 tabBar的選項
 pay.tabBarItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemRecents tag:1];
若要給它換圖片,用
pay.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"pay" image:[UIImage imageNamed:@"1"] selectedImage:[UIImage imageNamed:@"1"]];
給tabBar 設置多個視圖控制器
NSArray *vcArray = @[nav1,nav2,nav3,nav4,five,six];
tabBarController.viewControllers = vcArray;
設置當前選中的索引
tabBarController.selectedIndex = 0;
 1.建立多個視圖控制器
 2.建立UITabBarController的實例
 3.把UITabBarController的對象作爲根視圖添加到window上
 4.將全部的視圖控制器添加到tabbar上
 5.設置tabbar中的item

設置樣式
toolBar.barStyle = UIBarStyleDefault;
UIBarButtonItem *barButton1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:Nil];
設置BarButtonItem 之間的固定空間
UIBarButtonItem *FixedSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:self action:Nil];
寬度  FixedSpace.width  = 20;  
NSArray *itemArray = @[FixedSpace,barButton2,FixedSpace,barButton3];
[toolBar setItems:itemArray animated:YES];

ActionSheet 中的按鈕是從上到下來按順序設置索引值的
AlertView 中的按鈕中「取消」的索引值是0,其餘的按順序設置

若要使用系統的代理方法,要在.h 文件聲明類的後面加上<UI XXX Delegate>

第四周

代理
若是一個頁面以及上面的內容會在不一樣的時候出現,此時能夠把這個相同的東西封裝到一個類當中, 若此頁面出現的時候須要調用一些方法,此時爲了區分它們,咱們能夠在封裝類的頭文件中聲明一個 id 類型的對象(delegate),並在@end 下面用@protocol聲明此對象的方法(此方法的實現內容在具體出現的頁面中實現),讓其在須要用的時候調用。
@end
@protocol XXXDelgate <NSObject>
@optional
- (void)myView:(UIView *)myView clickedButtonAtIndex:(NSInteger)buttonIndex;
@end

繼承於 UIView的類所創造的對象能夠打點調用 hidden 設置爲 YES 讓其隱藏。

數據源   pickerView.dataSource = self;   有兩個必須實現的方法
代理   pickerView.delegate = self;
[pickerView selectedRowInComponent:0]; 得到第0區的第Row行
刷新第一個區  [pickerView reloadComponent:1];
選中第1區的第0行[pickerView selectRow:0 inComponent:1 animated:YES];

#pragma mark  雜注

設置樣式
datePicker.datePickerMode = UIDatePickerModeDateAndTime;
獲取picker的時間
NSDate *date = picker.date;
建立時間格式化器
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
 設置date的格式
[dateFormatter setDateFormat:@"yyyy-MMMM-dd-EEE-aa"];
把時間轉換成字符串
NSString *dateString = [dateFormatter stringFromDate:date];
yy: 年的後2位   yyyy: 完全年  
MM: 月,顯示爲1-12  MMM: 月,顯示爲英文月份簡寫,如Jan  MMMM: 月,顯示爲英文月份全稱,如Janualy
dd: 日,2位數表示,如02  d: 日,1-2位顯示,如 2
EEE: 簡寫星期幾,如Sun  EEEE: 全寫星期幾,如Sunday
aa: 上下午,AM/PM
H: 時,24小時制,0-23
K:時,12小時制,0-11
m: 分,1-2位  mm: 分,2位
s: 秒,1-2位  ss: 秒,2位  S: 毫秒
Z:  時區
經常使用日期結構:
yyyy-MM-dd HH:mm:ss.SSS
yyyy-MM-dd HH:mm:ss
yyyy-MM-dd
MM dd yyyy    

第五週

獲取標題寬度
width = button.titleLabel.frame.size.width;
UIFont *font = [UIFont systemFontOfSize:17];
CGSize size = [@"百度" sizeWithFont:font];

webView  網頁視圖
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[self.view addSubview:_webView];   
//    建立 連接
NSURL *url = [[NSURL alloc] initWithString:@"http://www.baidu.com"];
//  建立請求
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
//    加載請求
[_webView loadRequest:request];

不能深度賦值
應該這樣:CGRect rect = rainImage.frame;
        rect.origin.y = 305;
        rainImage.frame = rect;

若是把 Image 蓋在 button 上面,在 image 上點擊 button 效果還會被觸發,若是是把 View 蓋在上面,button 效果不會被觸發。

UITableView
設置分割線的顏色 tableView.separatorColor
實現表的數據源方法
下面黃色部分能夠相互代替(寫在 tableView 的建立後面)
給 tableview 的 ReuseIdentifier 註冊一個 cell類,當 tableview 找不到能夠重用的 cell 時,就會自動建立一個這種類型的 cell
[_table registerClass:[UITableViewCell class]  forCellReuseIdentifier:@"cell"];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"cell";
    //    在隊列中查詢有沒有能夠重用的單元格
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    //    若是沒有單元格 就去建立新的單元格
    if (!cell)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    return cell;
}
若是是自定義表加載 xib 時,要用
if (!cell)
    {
        //手動加載xib文件
        NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:Nil options:Nil];
         //強轉
        cell = (CustomCell *)[array objectAtIndex:0];
    }

自定義區頭後必定要記得設置區頭和區尾的高度
// 設置索引標題
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    return _array;
}
// 完成編輯
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    (此方法寫上之後向右劃定單元格會出現刪除按鈕,移除單元格的方法也就寫在這個方法裏面)
}

//設置是否能夠移動
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
//改變數據
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
    找到sourceIndexPath所在的位置(區、行)並把它從當前的數組中移除,而後把                                  sourceIndexPath加入到destinationIndexPath所在的位置(區、行),完成操做後必定要刷新表
}
刷新表的兩種方法:
1.[_tableView reloadData];
2.  NSIndexSet  索引集合 把將要改變的區加入到索引集合中  NSMutableIndexSet  可變的索引集合
 NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSetWithIndex:section];
[_tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationFade];
第二種方法比較高效
刷新表的時候,表的數據源方法和代理方法都要從新執行一次

Rotation 旋轉
順時針旋轉90
Button.transform = CGAffineTransformMakeRotation(M_PI_2);
transform默認爲CGAffineTransformIdentity

//    獲取最後一行的索引
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:_messageArray.count - 1 inSection:0];
//    _tableView滑動
    [_tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

//    自適應高度
    CGRect rect = [contentText boundingRectWithSize:CGSizeMake(160, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:17]} context:Nil];

UIImage *old = _whoSay ?[UIImage imageNamed:@"bubbleSelf"]:[UIImage imageNamed:@"bubble"];
UIImage *image = [old stretchableImageWithLeftCapWidth:10 topCapHeight:10];
imageView.image = image;

第六週

NSNumber 可以把基本類型的數據包裝成一個對象,此對象能夠存進數組。
    _sectionOpenArray = [[NSMutableArray alloc]initWithObjects:[NSNumber numberWithBool:NO], [NSNumber numberWithBool:NO],[NSNumber numberWithBool:NO],nil];
利用 NSNumber 實現 BOOL 值的轉換來改變tableView 中區的打開與關閉
[_sectionOpenArray replaceObjectAtIndex:button.tag withObject:[NSNumber numberWithBool:![[_sectionOpenArray objectAtIndex:button.tag] boolValue]]];

設置 alert 的樣式,不一樣樣式上面的 textfield 數量和類型不一樣
    alert.alertViewStyle = UIAlertViewStylePlainTextInput;
    [alert textFieldAtIndex:0].placeholder = @"用戶名";

用 alert 在 tableView 中添加一個分組
if (alertView.tag == 100)
   {
      //首先在好友數組中添加一個新的數組,用來存放這個區的好友
      [_friendArray addObject:[NSMutableArray arrayWithCapacity:0]];
      //而後再分組名稱數組中添加這個新分組的名字
      NSString *name = [alertView textFieldAtIndex:0].text;
      [_sectionNameArray addObject:name];
      //最後在控制打開關閉的數組中給這個新區添加一個 NSnumber,用來標記它的打開狀態
      [_sectionOpenArray addObject:[NSNumber numberWithBool:NO]];
      [_table reloadData];
   }

//從 iOS7 開始,狀態欄和 navigationBar 與 viewController 合爲一體(ViewController 的 View 左上角從屏幕左上角開始),爲了保證 tableview 或者 scrollView 頂部的內容不被 navigationBar 擋住,ViewController回自動給自身上的 scrollerView 頂部添加64的 inset,若是不須要這個 inset,automaticallyAdjustsScrollViewInsets設置爲 NO 便可。
    self.automaticallyAdjustsScrollViewInsets = NO;
    _table.contentInset = UIEdgeInsetsMake(64, 0, 0, 0);

    //刷新控制器
    UIRefreshControl *control = [[UIRefreshControl alloc] init];
    //設置菊花顏色
    control.tintColor = [UIColor redColor];
    //設置下拉刷新標題
    NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"下拉刷新"];
    [str setAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:20],NSFontAttributeName,[UIColor redColor],NSForegroundColorAttributeName, nil] range:NSMakeRange(0, 4)];
    control.attributedTitle = str;
    //把刷新控制器和tableViewController結合
    self.refreshControl = control;

    //中止下拉刷新的轉動動畫
    [self.refreshControl endRefreshing];

爲何要管理內存?
計算機的內存是有限的,若是咱們須要使用一個對象,會在內存中建立這個對象,內存使用量就會愈來愈多,若是隻建立,不去釋放,那麼就會形成內存撐爆。因此,咱們在使用一個對象時建立,再也不使用這個對象時,要把它釋放。

不一樣語言管理內存的方式
Java:全自動內存管理:Java 運行時,每隔一段時間就會自動檢查內存當中的全部對象,當發現再也不使用的對象時,就會把這個對象從內存中釋放。這個功能叫作 Java 垃圾回收機制。這種內存管理機制使用方便,可是運行效率低。
C++:全手動內存管理:當須要使用一個對象時建立,肯定再也不使用這個對象時,手動把它釋放掉。這種內存管理機制使用麻煩,可是運行效率高。
OC:經過引用計數來管理內存(半自動管理內存):對象的引用計數就是標記當前有多少個其餘對象正在使用這個對象。當其餘對象須要使用這個對象時,要把這個對象的引用計數加1,當某個其餘對象再也不使用這個對象時,要把這個對象引用計數減1。一旦某個對象的引用計數爲0,那麼它就會被系統釋放掉。

*全局指針須要在dealloc中release。 *局部指針須要在方法結束前release
super dealloc目的是釋放掉父類的全局指針指向的對象。
super dealloc必須寫在最後,由於要先釋放本身的全局屬性,再釋放父類的全局屬性
經過alloc,new,copy建立出來的對象,引用計數爲1 其餘的方式建立的對象,都是延遲釋放的。   new就至關於alloc+init
retain方法使一個對象引用計數+1    release方法使一個對象引用計數-1
若是一個指針指向了一個對象,那麼這個指針指向另一個對象時,須要先把以前指向的對象release一次。不然就會致使內存泄露。
*引用計數管理原則:誰建立,誰釋放,誰使用,誰管理。
alloc的數量+retain的數量=release的數量

把對象放進數組後,數組會對這個對象的引用計數+1
當數組移除某個對象時,這個對象的引用計數-1
當數組將要被釋放時,會對這個內部的全部對象release一次。

當一個視圖添加到父視圖上時,父視圖會對這個視圖引用計數+1
當一個視圖將要被釋放時,會對本身的全部子視圖release一次。

用buttonWithType建立的button,addSubview以後不須要release

alertView show以後會致使alert引用計數增長。 alertView show以後馬上release

模態彈出一個vc以後,vc的引用計數會增長。  vc模態彈出或者push以後馬上release

*若是property爲retain(copy)形式,當打點調用賦值時,會先對之指向的對象release一次,再對新指向的對象retain(copy)一次

對於對象的set方法,須要先對以前的對象release一次,而後對新的對象retain一次

對於全局的timer通常須要在界面消失的時候中止,而不是dealloc中中止,由於timer若是不中止,那麼timer的target就不會釋放。dealloc就不會執行。
NSTimer只要還在執行,即便引用計數爲0,也不會被釋放,直到timer中止纔可能被釋放。

UIImage的imageNamed方法雖然是延遲release的,可是並不會在事件循環結束的時候release。

delegate的property要用assign描述,不然會致使循環引用,最後兩個對象都釋放不掉

//用storyboard設計的viewController須要用UIStoryboard加載
    UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    ViewController *vc = [board instantiateInitialViewController];

單例類
一、單例類只有一個實例(對象)
二、單例類必須提供一個得到這個惟一實例的方法
三、單例類可以自動建立這個惟一的實例
自定義單例類
static Singleton *__singleton = nil;
+(Singleton *)defaultSingleton{
    
        //爲了防止多個線程同時判斷單例是否存在,從而致使同時建立單例。判斷的時候必須加線程同步。
    @synchronized(self){
        if (!__singleton) {
            __singleton = [[Singleton alloc] init];
        }
    }
    return __singleton;
}
//爲了防止人爲建立單例類,重寫alloc方法。
+ (id)alloc{
        //dispatch_once 的block中的代碼當程序運行後只會被執行一次。
        //單例類的建立最好用dispatch_once。
        //使用dispatch_once就不須要再進行判斷,也不須要關心線程同步。
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        __singleton = [super alloc];
    });
    return __singleton;
}

通知是 iOS中的一種調用機制,當發送通知時,不須要關心誰來接收,須要接收這個通知的對象須要本身去監聽這個通知。
 通知和代理的區別:相同之處,均可以實現回調,均可以傳參。不一樣之處,代理只能一對一調用,並且必須明確代理對象,通知能夠實現多對多調用,並且不須要關心通知的接收者;代理的協議方法能夠有返回值,可是通知的調用方法不能加返回值。

UIApplication就是單例類,咱們使用的時候沒有alloc 而是經過sharedApplication找到單例對象[UIApplication sharedApplication]
NSNotificationCenter是單例類。通知中心相似於廣播站,發送任何通知都必須經過通知中心發送。
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
//字典,也是一種對象的容器,和數組不一樣的是,數組中的對象按照順序存儲,而字典中的對象按照鍵值對存儲。
NSDictionary *dic = [[NSDictionary alloc] initWithObjectsAndKeys:color,@"color", nil];
//NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:color,@"color", nil];
//postNotification,發送一個通知
//第一個參數name是發送的通知的名字,用來區分不一樣的通知。
//第二個參數object是通知的發送者,通常都寫self
//第三個參數是通知的參數,用來傳參.
[center postNotificationName:@"changeColor" object:self userInfo:dic];

//addObserver添加一個監聽者(讓某個對象能夠接收通知)。
        //第一個參數observer就是添加的監聽者,就是讓哪一個對象去接受通知
        //第二個參數selector當監聽者收到通知時調用的方法。
        //第三個參數name,監聽的通知名字,只監聽哪一個通知。
        //第四個參數object,限定通知來源(只接受某個對象發的通知),若是不限定,寫成nil
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveChangeColorNotification:) name:@"changeColor" object:nil];

- (void)receiveChangeColorNotification:(NSNotification *)noti
{
//當收到通知時調用方法會傳過來一個NSNotification類型的參數,這個參數包含了name,object,和userInfo。
    self.view.backgroundColor = [noti.userInfo objectForKey:@"color"];
}
removeObserver取消全部的通知監聽。
*當一個對象將要被釋放時,若是這個對象註冊有監聽通知,那麼在釋放前(也就是dealloc中)必須取消全部的監聽,不然就會致使程序崩潰
[[NSNotificationCenter defaultCenter] removeObserver:self];

- (void)introduceSelf
{
    NSLog(@"%@",self);
}
//description方法用來設置NSLog這個對象時輸出的內容。若是不設置,默認輸出爲內存地址
- (NSString *)description
{
    return [NSString stringWithFormat:@"我叫%@,今年%d歲,性別%@",_name,_age,_sex?@"男":@"女"];
}


//UIApplicationDidEnterBackgroundNotification應用程序已經進入後臺的通知。
//UITextFieldTextDidChangeNotification輸入框中內容改變時的通知
//UIKeyboardWillChangeFrameNotification鍵盤的frame將要發生改變的通知
NSValue可以把結構體封裝成對象,就能夠放入數組或字典。
    NSValue *value = [noti.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
        //得到鍵盤的座標
    CGRect rect = [value CGRectValue];
        //得到動畫時間
    float duration = [[noti.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
    int curve = [[noti.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];

數據的存儲
沙盒:在存儲器中一塊獨立的空間,這個空間中存儲了一個應用,以及這個應用的數據,那麼這塊空間就叫作這個應用的沙盒。
沙盒運行模式:應用程序在運行時,對硬盤的操做權限僅限於本身沙盒內部,不能對沙盒外部的空間進行直接操做。
沙盒內部有4個文件夾, Documents,library,tmp,app  Documents 存儲應用的文檔文件,對於開發者最經常使用.      library 存儲應用設置或配置的相關信息,也存儲一些系統數據,提供給系統使用,通常狀況下不在這個文件夾下存儲文件.        tmp 臨時文件夾,用來存儲一些臨時文件      app 應用資源文件夾,存儲應用所須要的全部資源,此文件夾只能讀,不能修改.  

1.使用NSUserDefaults存儲數據
    // NSUserDefaults 用戶數據存儲器,經常使用來存儲和一些用戶信息或用戶設置有關的一些數據
    // NSUserDefaults 單例類
    NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
    // NSUserDefaults 相似字典,但不是字典,它能夠存對象,還能夠存基本類型.
    [user setObject:name forKey:@"name"];
    [user setInteger:age forKey:@"age"];
    [user setBool:sex forKey:@"sex"];
    // NSUserDefaults 修改後必須馬上同步一次(存儲到硬盤),不然修改無效.
    [user synchronize];
    // NSUserDefaults 中的內容存儲在沙盒下 library 文件夾中
從 NSUserDefaults 中讀取數據
    NSString *name = [[NSUserDefaults standardUserDefaults] objectForKey:@"name"];
    int age = [[NSUserDefaults standardUserDefaults] integerForKey:@"age"];
    BOOL sex = [[NSUserDefaults standardUserDefaults] boolForKey:@"sex"];
    _name.text = name;
    _age.text = [NSString stringWithFormat:@"%d",age];
    _sexControl.selectedSegmentIndex = sex;

2.使用數組存儲數據
    NSArray *array = [[NSArray alloc]initWithObjects:name,_age.text,sex?@"男":@"女", nil];
    //Directory (計算機文件或程序)的目錄
    //Appending 附加 添加 貼上   Component 構成 成分  
    //NSHomeDirectory()找到當前應用的沙盒路徑。
    //stringByAppendingPathComponent當一個路徑後追加路徑。
    NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/abc.xml"];
    //writeToFile 把數據存入文件,第一個參數是路徑名,第二個參數是是否原子性(是否使用臨時文件存儲).
    [array writeToFile:path atomically:NO];
    [array release];
    //文件名的後綴和文件內容沒有關係,後綴僅僅是標記了這個文件的類型,也就是這個文件應該用什麼工具去打開.
從文件當中讀取數組.
    NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/abc.xml"];
    NSArray *array = [[NSArray alloc]initWithContentsOfFile:path];
    _name.text = [array objectAtIndex:0];
    _age.text = [array objectAtIndex:1];
    _sexControl.selectedSegmentIndex = [[array objectAtIndex:2] isEqualToString:@"男"]?0:1;
//判斷某個文件是否存在
[[NSFileManager defaultManager]fileExistsAtPath:directoryPath]

//建立一個文件夾
 [[NSFileManager defaultManager ] createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:nil];

//建立一個文件
[[NSFileManager defaultManager]createFileAtPath:filePath contents:nil attributes:nil];

3.使用字符串拼接存儲數據
    NSString *string = [NSString stringWithFormat:@"%@|%@|%@",name,_age.text,sex?@"女":@"男"];
    NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/string.txt"];
    //把字符串存入文件,第一個參數是存儲路徑,第二個參數是原子性,第三個參數是編碼方式,iOS 的默認編碼方式是 UTF8編碼,第四個參數是若是寫入失敗,失敗的緣由.
    [string writeToFile:path atomically:NO encoding:NSUTF8StringEncoding error:nil];
3.
     NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/string.txt"];
    NSString *string  = [[NSString alloc]initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
    //按照某個字符串分割成一個長字符串,獲得一個數組,數組中就是分割成的若干個字符串.
    NSArray *arr = [string componentsSeparatedByString:@"|"];
    _name.text = [arr objectAtIndex:0];
    _age.text = [arr objectAtIndex:1];
    _sexControl.selectedSegmentIndex = [[arr objectAtIndex:2] isEqualToString:@"男"]?0:1;
    [string release];

NSUserDefaults只能存系統自帶的數據類,例如NSArray,NSString,int,BOOL等,自定義的類不能存。
NSArray(NSDictionary)只有當存儲的對象都是系統自帶的數據類時,才能夠writeToFile,若是數組中存有自定義類,那麼就不能writeToFile.
NSData數據類,存儲了一段二進制數據。NSDate能夠直接存入文件
    //對於自定義類,若是想存入文件,必須先轉化爲二進制數據。這個轉化的過程叫作對象序列化。
    //只有實現了NSCoding協議,這個類才能被轉化爲二進制數據
    //NSKeyedArchiver編碼器,可以把實現了NSCoding協議的對象編碼成二進制數據.
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:p];
    NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/data.plist"];
    [data writeToFile:path atomically:NO];
從文件中讀取NSData
  NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/data.plist"];
  NSData *data = [NSData dataWithContentsOfFile:path];
  //NSKeyedUnarchiver解碼器,可以把二進制數據還原成原來的對象。
  People *p = [NSKeyedUnarchiver unarchiveObjectWithData:data];
  _nameField.text = p.name;
  _ageField.text = [NSString stringWithFormat:@"%d",p.age];
  _sexControl.selectedSegmentIndex = p.sex;

實現 NSCoding 協議(先在.h 文件中用<NSCoding>在想要實現的類後追加)
    //編碼方法。
- (void)encodeWithCoder:(NSCoder *)aCoder{
        //若是父類也遵照NSCoding協議,須要先調用super encodeWithCoder
        //在編碼方法中,把須要編碼的數挨個進行編碼
    [aCoder encodeObject:_name forKey:@"name"];
    [aCoder encodeInt:_age forKey:@"age"];
    [aCoder encodeBool:_sex forKey:@"sex"];
}

    //解碼方法。
- (id)initWithCoder:(NSCoder *)aDecoder{
    self = [super init];
        //在解碼方法中,對編碼過的屬性逐一解碼
    if (self) {
        _name = [[aDecoder decodeObjectForKey:@"name"] copy];
        _age = [aDecoder decodeIntForKey:@"age"];
        _sex = [aDecoder decodeBoolForKey:@"sex"];
    }
    return self;
}

指針自己也是個變量,也須要佔用內存,因此指針自己也有內存地址。
     // NSString **str;兩個星的指針叫作雙指針,也就是指向指針的指針(指向指針的內存地址)。
&取地址符,得到一個指針的內存地址
     //NSString **dString = &string;
/方法傳參時若是要傳遞一個指針,那麼不能直接寫這個指針,由於寫成指針實際傳遞的是這個指針指向的對象,因此若是要傳遞指針,參數必須寫成指向這個指針的指針。

//  NSFileManager  文件管理器,對文件進行刪除,移動,複製,剪切等操做。
        //NSFileManager也是單例類
    NSFileManager *manager = [NSFileManager defaultManager];
    NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/string.txt"];
    NSError *err = nil;
        //刪除一個文件,若是刪除失敗,輸出失敗的緣由
    if (![manager removeItemAtPath:path error:&err]) {
        NSLog(@"%@",err);
    }

/建立文件夾
    NSFileManager *manager = [NSFileManager defaultManager];
    NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/abc/123"];
        //withIntermediateDirectories是否自動建立路徑中不存在的文件夾。
    [manager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];

//查看文件屬性
- (IBAction)checkFileAttribute:(UIButton *)sender
{
    NSFileManager *manager = [NSFileManager defaultManager];
    NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/string.txt"];
    NSDictionary *dic = [manager attributesOfItemAtPath:path error:nil];
    NSLog(@"%@",dic);
}

UIImagePickerController  圖片選擇器
把圖片轉化成data的
    NSData *data = UIImageJPEGRepresentation(_imageView.image, 0.5);
//圖片可編輯
        controller.allowsEditing = YES;

第七週

//FMDB是對sqlite3的封裝,內部使用的也是sqlite3,因此要使用FMDB,須要先導入sqlite3庫
//FMDatabase數據庫操做類,能夠打開或建立一個數據庫文件。
    FMDatabase          *_db;
//打開或建立一個數據庫文件
    _db = [[FMDatabase alloc]initWithPath:[NSHomeDirectory() stringByAppendingPathComponent:@"Documents/data.sqlite"]];
    //打開數據庫
    [_db open];
    //在這個數據庫中建立一張表  executeUpdate 執行一條修改語句
    [_db executeUpdate:@"CREATE TABLE IF NOT EXISTS people(peopleID INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT,phone TEXT)"];
    //FMResultSet 結果集,查詢出來的數據有可能不少條,因此放在了一個結果集中
    FMResultSet *set = [_db executeQuery:@"SELECT * FROM people"];
    //next 方法前往下一條記錄,若是存在下一條記錄返回 YES,不存在返回 NO.存在這條記錄的話,把此記錄封裝成 people 對象,裝進數組.(經過 while 循環遍歷結果集)
    while ([set next])
    {
        People *p = [[People alloc]init];
        p.name = [set stringForColumn:@"name"];
        p.peopleID = [set intForColumn:@"peopleID"];
        p.phone = [set stringForColumn:@"phone"];
        [_array addObject:p];
        [p release];
    }
    [set close];
    //關閉數據庫
    [_db close];

//把新添加的人寫入數據庫
    [_db open];
    //FMDB中 SQL 語句的佔位符(?)只能用 NSString 替代,不能用 int
    [_db executeUpdate:@"INSERT INTO people(name,phone)VALUES(?,?)",p.name,p.phone];
    //SELECT MAX(peopleID) 搜索表中最大的peopleID,
    FMResultSet *set = [_db executeQuery:@"SELECT MAX(peopleID) FROM people"];
    [set next];
    int maxID = [set intForColumnIndex:0];
    p.peopleID = maxID;

//執行刪除操做時,要先從數據庫中刪除
    People *p = [_array objectAtIndex:indexPath.row];
    [_db open];
    [_db executeUpdate:@"DELETE FROM people WHERE peopleID=?",[NSString stringWithFormat:@"%d",p.peopleID]];
    [_db close];

/*----這兩個方法配套使用,是 UIViewController 的方法*/
- (BOOL)shouldAutorotate{
    return YES;
}
    //設置支持的屏幕方向
- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscape;
}
/*----_________________*/

獲取屏幕的旋轉角度
 UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
設置標籤的旋轉(到的)角度
 lab.transform = CGAffineTransformMakeRotation( 270 * M_PI/180);

第八週

通信
是客戶端與服務器之間的通訊
服務器(客戶端):1.安裝了服務器(客戶端)軟件的電腦    2.服務器(客戶端)軟件

IP 地址:Internet protocol 網絡傳輸協議的邏輯地址
IPv4 地址是由4個  0到255  的數字組成
互聯網中一臺計算機發出的數據經過 IP 地址才能把數據準確的發送到另一臺計算機

域名,俗稱網址,爲了方便記憶和輸入,進行通訊時,不直接使用 IP 地址,而是使用域名.

DNS 服務:域名解析服務,可以把域名解析爲 IP 地址

MAC地址:Media Access Control  接入互聯網計算機的物理地址或網卡地址 經過物理地址識別主機

端口號: 是計算機與外界通信交流的出口。   物理接口,協議端口    192.169.0.1:80 冒號後面的就是端口號
在計算機上運行的軟件若是須要上網,就必須有一個端口號,用來區分網絡返回的數據用於哪一個軟件。範圍0-65535。一些號被特定的使用如:用於網絡的80端口,用於FTP服務的21端口。

HTML:Hyper Text Mark-up Language 超文本標記語言,用來設計一個網頁,任何網頁的實質都是 html 標籤對.

URL:惟一資源標識符.(連接地址) 表明一個資源的位置。能夠是網絡上的,能夠是本地的。

http協議: 超文本傳輸協議
http傳輸 以報文形式傳輸,  分爲請求報文和響應報文
請求報文分爲請求行,請求頭,和請求體。  
請求行:請求方式(GET,POST)空格 IP 地址後的url 空格 http 版本
回車         
請求頭:contentLength = 0    connection = 「close」
回車
回車
請求體:請求內容,能夠爲空也能夠傳數據

telnet localhost 8080
GET /MyServer/ HTTP/1.0

Host=localhost
Connection=close   

//把接收到服務器返回的data類型的數據 轉換成String類型的數據
NSString *str = [[NSString alloc] initWithData:_buffer encoding:NSUTF8StringEncoding];
    NSLog(@"str  %@",str);

響應報文
1.響應行:HTTP 版本 響應狀態碼(2XX 正常響應 4XX 異常響應)
GET 請求:把請求的參數寫在請求的 url 以後,在 url 最後加?而後後面寫參數,參數與參數之間用&分割(url?XXX=XXX&XXX=XXX)
GET請求參數長度受限,並且不安全.

POST 請求:把參數寫在請求體中,這種請求方式相對安全.

JSON數據
[]表示數組
{}表示字典

[{name:張三,qq:123,sign:我今年5歲了},{name:李四,qq:333,sign:我撿了100塊}]

OAuth 2.0認證過程
1.客戶端重新浪微博請求一個認證界面,而後將這個認證界面呈現給用戶。
2.用戶在認證界面填寫完帳號密碼並點肯定時,認證界面會把帳號密碼直接發送給新浪微博(不經過客戶端)。
3.新浪微博驗證用戶輸入的帳號密碼,若是輸入正確,新浪微博回交給客戶端一個 code。
4.客戶端拿到 code 以後,用 code 去請求 token。
token 就是這個用戶的通行證。

在當前時間的基礎上加上一個時間
NSDate *date = [[NSDate date] dateByAddingTimeInterval:expires.doubleValue]

//dateWithTimeIntervalSinceNow
//於如今相隔多少秒的一個時間
//正數,多少秒後,負數,多少面前
NSDate* date = [NSDate dateWithTimeIntervalSinceNow:[expires intValue]];

比較兩個時間的大小 NSOrderedDescending降序 說明前者比後者大
[date compare:nowDate] == NSOrderedDescending

//實現斷點下載,首先要獲取已經下載的文件的大小。
 NSDictionary *att = [[NSFileManager defaultManager] attributesOfItemAtPath:[self filePath] error:nil];
 unsigned long long size = [att fileSize];
//*當繼續下載時,應該告訴服務器,客戶端已經下載好了一部分數據,只須要把下載好的數據後面的數據傳輸過來便可。
//*請求頭中Range表明下載的範圍,從總數據的第幾個字節以後開始下載就寫成xx-
[request addValue:[NSString stringWithFormat:@"bytes=%qu-",size] forHTTPHeaderField:@"Range"];

上傳文件或圖片時,要用到固定的HeaderField   
[request addValue:@"multipart/form-data" forHTTPHeaderField:@"Content-Type"];

//UIImagePNGRepresentation把一個UIImage轉成png格式的 NSData。
//UIImageJPEGRepresentation把一個UIImage轉成jpg格式的 NSData。
//0.7是壓縮比例,把圖片壓縮後轉成DATA
NSData *data =  UIImageJPEGRepresentation(_imageView.image, 0.7);
//把須要上傳的數據放入請求體
[request setHTTPBody:data];

unsigned long long size = [att fileSize];
 //告訴服務器上傳的文件的大小
 [request addValue:[NSString stringWithFormat:@"%qu",size] forHTTPHeaderField:@"Content-Length"];
 //生成一個文件的輸入流
    NSInputStream *stream = [NSInputStream inputStreamWithFileAtPath:path];
 //當上傳大文件時,爲了節省內存,不直接把全部數據都讀入內存,而是使用數據流一點一點讀取。
 //設置請求體的輸入流
 [request setHTTPBodyStream:stream];

第十週


//自定義類型   在#import 下,@interface 上 定義之後,在本類中後者就能夠代替前者使用
typedef int myInt;
typedef NSString String;
//定義一個block類型
typedef int (^myBlock)(int a,int b) ;


//block不能使用局部變量,可使用全局變量,若是block中須要使用局部變量,須要在定義的變量前+ __block
//局部變量在block中只讀。並且,是一次性賦值(把c的值copy到block中,之後c的值改變,並不會影響到block中的c)
//全局變量,__block變量,static變量,在block中引用的話,引用的是變量,而不是變量的值,也就是說,引用以後,變量發生改變的話,block中的值也會發生變化

//若是屬於某個對象的block當中又使用到了這個對象,就會形成循環引用(對象和block的循環引用),致使最後對象釋放不掉,因此,當屬於某個對象的block使用這個對象時,應該再定義一個__block的指針指向這個對象,在block中使用__block指針。
//若是是ARC,用__weak
__block SecondVC *safeSelf = self;
    self.block = ^{
        safeSelf.view.backgroundColor = [UIColor redColor];
    };

//全局的block(在棧內存中的block)須要對block塊內局部變量的引用計數+1(塊內全局變量不變)。
//某些狀況下,不能使block的對象引用計數增長,那麼在這個指針前+__block。
__block NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"123", nil];
//局部的 block 塊內對象的引用計數均不變
    self.block = ^{
        [array addObject:@"222"];
        [_array addObject:@"222"];
    };

//GCD中使用線程隊列實現多線程。
  //咱們能夠在一個線程隊列中加入一段代碼,線程隊列就會執行這個段代碼。
  //dispatch_queue_t 線程隊列,
  //dispatch_queue_create函數,建立一個新的線程隊列,其中第一個參數是線程隊列的標籤(名字)。第二個參數是隊列的類型。
  //線程隊列分爲串行隊列和並行隊列,若是要建立串行隊列,第二個參數寫DISPATCH_QUEUE_SERIAL,並行隊列寫DISPATCH_QUEUE_CONCURRENT。
 dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);

  //雖然並行隊列也能夠建立,可是通常不去建立並行隊列,而是找到系統自帶的global並行隊列使用。
 dispatch_queue_t tQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//dispatch_sync在線程隊列中同步執行一個block
//同步執行,至關於waitUntilDone,當前代碼先中止,直到分線程的block中的代碼執行完畢,當前線程才繼續往下執行。
//異步執行,開啓一個分線程後,當前線程不去等待分線程執行完畢,直接往下執行。
dispatch_async(concurrentQueue, ^{
    NSLog(@"%@",[NSThread currentThread]);
    [NSThread sleepForTimeInterval:1];
});

//dispatch_get_main_queue得到主線程隊列,主線程只有一個,因此,主線程是串行隊列。
        dispatch_queue_t mainQueue =  dispatch_get_main_queue();
        //把刷新UI的代碼放在主線程中執行
        dispatch_async(mainQueue, ^{
            _imageView.image = image;
        });
    });

//dispatch_suspend暫停一個線程隊列,暫停以後,正在執行的block還會繼續執行,這個block執行完以後,後面的block不會繼續執行。      dispatch_suspend(_queue);
//dispatch_resume繼續一個線程隊列,繼續以後,隊列中的block會繼續執行。
    dispatch_resume(_queue);

//建立出來的線程隊列用完以後須要release
    dispatch_release(queue);

//dispatch_semaphore_t 線程信號量,dispatch_semaphore_create建立一個信號量,參數爲初始信號量。
    dispatch_semaphore_t sem = dispatch_semaphore_create(0);
//dispatch_semaphore_signal給某個信號量發送一個信號,做用是使這個信號量+1.       
    dispatch_semaphore_signal(sem);
 //dispatch_semaphore_wait等待信號量(等待信號量大於0),當信號量等於0時,當前線程會在這一行代碼等待,直到sem信號的信號量大於0,當信號量大於0時,當前線程會對信號量-1,而後繼續往下執行。
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);

//設置一個信號量,信號量的值就是最大併發數。
    dispatch_semaphore_t sema = dispatch_semaphore_create(10);
-使用semaphore設置併發隊列的最大併發數-
        //建立一個併發隊列
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        //每當向隊列中加入一個block時,先讓線程等待,信號量足夠時(大於0),線程執行,不然線程等待。
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
        //code
        //code
        //code
        //code
            //當block執行完畢時,給信號量發送信號,使信號量+1
        dispatch_semaphore_signal(sema);
    });

//dispatch_after延遲執行一個block
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"3秒以前點擊了button");
    });

//NSOperationQueue,操做隊列。
     NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
//maxConcurrentOperationCount設置隊列的最大併發數,當把最大併發數設置爲1時,這個隊列就至關於串行隊列。
     queue.maxConcurrentOperationCount = 10;

//addOperationWithBlock把一個block封裝成NSOperation,而後把這個operation放進操做隊列中執行。
    [queue addOperationWithBlock:^{
        NSLog(@"%d",[NSThread isMainThread]);
          //currentQueue獲得當前線程所在的操做隊列。
        NSOperationQueue *qu = [NSOperationQueue currentQueue];
          //mainQueue獲得主線程操做隊列
        NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
    }];

第十一週

    //setApplicationIconBadgeNumber設置應用程序icon的角標
    //申請推送權限,IOS8開始,須要申請推送權限,才能顯示icon角標
    [[UIApplication sharedApplication] registerUserNotificationSettings:nil];
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:3];
    //badgeValue屬性,角標。
    self.navigationController.tabBarItem.badgeValue = nil;

    frame是相對於父類的座標系,bounds 是相對於本身的座標系

字符串的逆轉
NSString *str = @"a,b,c,d";
    NSMutableString *newStr = [[NSMutableString alloc]initWithCapacity:0];
    @autoreleasepool {
        for (int i = str.length-1; i>=0; i--)
        {
            [newStr appendString:[NSString stringWithFormat:@"%c",[str characterAtIndex:i]]];
        }
    }
    NSLog(@"%@",newStr);


//在圖片邊緣添加一個像素的透明區域,去圖片鋸齒
    CGRect imageRrect = CGRectMake(0, 0,_imageView.frame.size.width, _imageView.frame.size.height);
    UIGraphicsBeginImageContext(imageRrect.size);
    [_imageView.image drawInRect:CGRectMake(1,1,_imageView.frame.size.width-2,_imageView.frame.size.height-2)];
    _imageView.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();



2015.1.13
手勢 touch時間 核心動畫
/*iOS學習筆記之QuartzCore框架
 iOS編程給用戶視覺反饋其實都是經過QuartzCore框架來進行的,說白了,全部用戶最終看到的顯示界面都是圖層合成的結果,而圖層便是QuartzCore中的CALayer。
 一般咱們所說的視圖即UIView,並非直接顯示在屏幕上,而是在建立視圖對象的時候視圖對象會自動建立一個層,而視圖對象把要顯示的東西繪製在層上,待到須要顯示時硬件將全部的層拷貝,而後按Z軸的高低合成最終的顯示結果。
 CALayer本質上是一塊包含一幅位圖的緩衝區,由視圖建立的層爲隱式層,而手動建立的層稱爲顯示層。
 若是要在iOS上可以有良好的用戶體驗,動畫的過渡效果是必不可少的,而全部的動畫效果都是經過CAAnimation類的子類(CAAnimation是抽象類)來完成的。CAAnimation類的子類包括了 CAAnimationGroup,CAPropertyAnimation,CATransition,而CAPropertyAniamtion(同爲抽象類)也衍生了CABasicAnimation和CAKeyframeAnimation。用UIView的animation實現的動畫本質上也是經過CALayer來實現的,iOS系統中CALayer的不少屬性都是隱含有動畫效果的,若是不想要隱式動畫或者想要顯示動畫效果,均可以經過CATransaction來設置是否顯示動畫效果。同時,在CATransaction內可同時修改多個屬性,而後再一併同時渲染,另外CATransaction仍是可嵌套的。
 CABasicAnimation是一個最多隻能有兩個關鍵幀的動畫,而 CAKeyframeAnimation除了可含有多個關鍵幀,並且還能夠修改每一個關鍵幀的速度。
 CATransition可以爲層提供移出以及移入屏幕的效果。蘋果提供的全部動畫類型在http://iphonedevwiki.net/index.php/CATransition這裏有介紹,可是api只開放了其中的四種,固然你能夠調用未公開的api,可是假如蘋果之後出於安全仍是什麼緣由調整接口的話,就不必定能用了,因此最好仍是不要調用私有api,何況還有許多能夠替代的方法,例如 @"flip」,@"pageCurl」這些type是屬於未公開的,

//成爲第一響應者
 [self becomeFirstResponder];













web

相關文章
相關標籤/搜索