重點知識
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