30天學(xué)會(huì)ios開發(fā)"1.基本數(shù)據(jù)類型"

數(shù)據(jù)也是一種美

ios 基本數(shù)據(jù)類型分為以下幾種,用好數(shù)據(jù)類型能讓你一看就是個(gè)老手~
1 NSString 字符串類型(還記得NS代表啥意思了嗎?現(xiàn)在蘋果已經(jīng)在慢慢移除這個(gè)前綴啦)

2 NSInteger 整形
當(dāng)使用int類型定義變量的時(shí)候,可以像寫C程序一樣,用int也可以用NSInteger,推薦使用NSInteger ,因?yàn)檫@樣就不用考慮設(shè)備是32位還是64位了,NSInteger在64位取值范圍是[2的-63次方]到[2的63次方減一]

3 NSUInteger 無符號(hào)整形(即沒有負(fù)數(shù))

4 NSArray 固定數(shù)組
數(shù)組內(nèi)可以塞入對(duì)象類型如 nsstring或者nsnumber,如果塞入int就會(huì)崩潰哦.一旦聲明,不可再更改其內(nèi)部的值.

5 NSMutableArray 可變數(shù)組
聲明后可再更改其內(nèi)部的值.

6 NSDictionary 固定字典
字典內(nèi)可以塞入對(duì)象類型如 nsstring或者nsnumber,如果塞入int也會(huì)崩潰哦.

7 NSMutableDictionary 可變字典
聲明后可再更改其內(nèi)部的值.

8 NSNumber 數(shù)字類,能形容一切的數(shù)字類型如cgfloat,int,long,float

9 CGFloat 浮點(diǎn)型(能表示包含小數(shù)的數(shù)字類型)
讓我們先掌握以上幾種數(shù)據(jù)類型吧

10 bool 布爾類型 YES ,NO 代表是與不是

數(shù)字類型介紹:

寫程序,最多接觸的就是數(shù)字啦,掌握好數(shù)字類型讓你事半功倍!
首先ios 推薦使用nsinterger nsuinterger cgfloat 他們其實(shí)都是int unsigned int float 的包含在32位和64位下nsinterger 等oc類型表示的范圍是有區(qū)別的,但是現(xiàn)在32位的ios設(shè)備已經(jīng)被淘汰了,所以并沒有區(qū)別了.
數(shù)據(jù)類型的一個(gè)比較大的問題就是類型轉(zhuǎn)換了

CGFloat tFloat = 10/1000;

得到的結(jié)果會(huì)是0 哦,surprise mother fxker!!!

原因
計(jì)算機(jī)中的運(yùn)算有個(gè)原則:
相同數(shù)據(jù)類型的值才能進(jìn)行運(yùn)算,而且運(yùn)算結(jié)果依然是同一種數(shù)據(jù)類型。因此,整數(shù)除于整數(shù),求出來的結(jié)果依然是整數(shù),會(huì)損失小數(shù)部分。
在計(jì)算中常常會(huì)忘記這個(gè),所以做除法時(shí)務(wù)必記得這樣!!!!!!!!

CGFloat tFloat = (CGFloat)10/1000;

NSNumber 作為oc 的數(shù)字類,方便大家繼續(xù)數(shù)字相關(guān)的處理

NSNumber *num = @(10); //oc 語法糖,快速轉(zhuǎn)換int 為 nsnumber

反之

int myInt = [intNumber intValue]; //對(duì)象轉(zhuǎn)換為整型值
      //[floatnumber floatValue]; //對(duì)象轉(zhuǎn)換為浮點(diǎn)
      //[doublenumber doubleValue]; //對(duì)象轉(zhuǎn)換為雙精度浮點(diǎn)值
  

nsnumber 最需要用到的地方就是將數(shù)字塞入nsarray 或者nsdictionary

//這個(gè)是對(duì)的
NSArray*array=[[NSArray alloc]init];
[array addObject:[NSNumber numberWithInt:6]];

//這個(gè)是錯(cuò)的
NSArray*array=[[NSArray alloc]init];
[array addObject:6];//程序會(huì)無法編譯通過的

此外數(shù)字處理最敏感的貨幣部分,可以使用NSDecimalNumber,其保留精度高,數(shù)字比較,四舍五入等方便計(jì)算.務(wù)必記得使用,同時(shí)可以定義數(shù)字的輸出格式,這樣在銀行或科學(xué)方面app會(huì)有用;

// 定義你數(shù)字的輸出格式 輸出為123,456.045 只保留小數(shù)點(diǎn)后三位
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = kCFNumberFormatterDecimalStyle;
NSString *num = @"123456.0453";
NSNumber *result111 = [NSNumber numberWithDouble:num.doubleValue];
NSString *string = [formatter stringFromNumber:result111];

附上數(shù)字與其他類型轉(zhuǎn)換方式

//字符串轉(zhuǎn)int
NSInteger lNumber = [sNumber integerValue]; 
//int 轉(zhuǎn)字符串
NSString* sNumber = [NSString stringWithFormat:@"%ld", lNumber];
//字符串轉(zhuǎn)nsnumber
NSNumber *myNumber = [f numberFromString:@"42"];
//float 轉(zhuǎn) NSInteger
NSInteger i = (NSInteger)1.345;

字符串類型介紹:

nsstring 字符串類型操作也十分豐富,本人在定義模型中基本上都用字符串類型,數(shù)字也使用字符串表示
初始化化一個(gè)字符串的方法為

//簡單聲明 "@"表示為oc nsstring類型字符串
NSString *str = @"123";//NSString 為對(duì)象類型,所以記得加*號(hào)
//將變量轉(zhuǎn)換為字符串  
NSString *string = [NSString stringWithFormat:@"%.2f",M_PI]; // %.2f表示保留小數(shù)點(diǎn)兩位

stringWithFormat 拼接時(shí)候的占位符一覽
%@ 對(duì)象 (非常常用)
%d, %i 整數(shù)
%u 無符整形
%f 浮點(diǎn)/雙字
%x, %X 二進(jìn)制整數(shù)
%o 八進(jìn)制整數(shù)
%zu size_t
%p 指針
%e 浮點(diǎn)/雙字 (科學(xué)計(jì)算)
%g 浮點(diǎn)/雙字
%s C 字符串
%.*s Pascal字符串
%c 字符
%C unichar
%lld 64位長整數(shù)(long long)
%llu 無符64位長整數(shù)
%Lf 64位雙字
%e 是實(shí)數(shù),用科學(xué)計(jì)數(shù)法計(jì)的

此外字符串的常用方法其實(shí)很多很多


//在字符串temp的基礎(chǔ)繼續(xù)添加temp 并組成一個(gè)新的字符串  
    NSString *str5 = [temp stringByAppendingString:temp];   
 //字符串以開頭比較  
    if([str0 hasPrefix:@"just"])  
   //字符串以結(jié)尾比較  
    if([str1 hasSuffix:@"coding"])  
 //字符串完全相等比較  
    if([str0 isEqualToString:str1])   //注意不要使用==來比較,這樣比較的是指針地址
//寫字符串到文件:writeToFile方法
NSString *astring = [[NSString alloc] initWithString:@"This is a String!"];
NSLog(@"astring:%@",astring);
NSString *path = @"astring.text";    
[astring writeToFile: path atomically: YES];

字符串判斷是否為空問題
看似簡單的nsstring 也有一個(gè)容易被坑的地方,那就是字符串判空.
判斷字符串為空:看似簡單的問題,有人會(huì)說不就使用[string isEqualToString:@""]或者更簡單的string.text == nil就行了嘛。但是并沒有考慮到其中存在的一些問題,例如當(dāng)字符串中存在空格或者換行時(shí)或者當(dāng)請(qǐng)求后臺(tái)數(shù)據(jù)時(shí)得到的是進(jìn)行JSON解析的時(shí)候, 如果解析出的NSDictionary中某個(gè)key對(duì)應(yīng)的value為空, 則系統(tǒng)會(huì)把它處理為NSNull類的單例對(duì)象。這些情況下,上面的判斷方法就不會(huì)起到作用。

+  (BOOL)isEmpty:(NSString *)aStr {
    if (!aStr) { //nil 當(dāng)然為空
        return YES;
    }
    if ([aStr isKindOfClass:[NSNull class]]) { //nsnull 也為空
        return YES;
    }
    //剔除空格和換行符
    NSCharacterSet *set = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    NSString *trimmedStr = [aStr stringByTrimmingCharactersInSet:set];
    if (!trimmedStr.length) {//長度為空
        return YES;
    }
    return NO;
}

json 問題
處理字符串,自然少不了json字符串和nsarray,nsdictionary的轉(zhuǎn)換,大家copy拿走吧

//array,dictinary 轉(zhuǎn)json串
+(NSString *)objectToJson:(id)obj{
    if (obj == nil) {
        return nil;
    }
    NSError *error = nil;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:obj
                                                       options:0
                                                         error:&error];
    
    if ([jsonData length] && error == nil){
        return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    }else{
        return nil;
    }
}

//nsarray,nsdictionary轉(zhuǎn)換為json字符串
+(id)jsonToObject:(NSString *)json{
    //string轉(zhuǎn)data
    NSData * jsonData = [json dataUsingEncoding:NSUTF8StringEncoding];
    //json解析
    id obj = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
    return obj;
}

小貼士: nsstring property在實(shí)踐中經(jīng)常使用copy,大家知道為什么嗎?
因?yàn)槭褂胏opy修飾之后,即使屬性拷貝來自可變字符串,也會(huì)被深拷貝成不可變字符串,也就是源字符串修改之后不會(huì)影響到屬性字符串,增強(qiáng)了代碼的健壯性。

//property nsstring 為copy 時(shí)
age = 21;
person.age = age; //age為copy
age = 22;
nslog(@"%d",person.age) //此時(shí)打印的是21,不收age的變化影響

NSString 能表示字串符,但是對(duì)于表示字符串的格式就無能為力了,之后還會(huì)在富文本章節(jié)內(nèi)介紹NSAttributedString.

NSArray 數(shù)組類型介紹

在工作中,我們經(jīng)常要做feeds流,列表展示之類的頁面.本質(zhì)上,就是對(duì)數(shù)組的顯示,所以掌握好數(shù)組真的非常重要,數(shù)組是用來儲(chǔ)存oc對(duì)象的一種數(shù)據(jù)結(jié)構(gòu),好比一節(jié)節(jié)的火車車廂,每個(gè)車廂里坐著一個(gè)oc對(duì)象,大家按照順序從頭節(jié)坐到末節(jié).(你想問這車廂具體有多少節(jié)呀,只要iphone內(nèi)存夠,這車廂就夠長!)
之前有說過數(shù)組分為NSArray和NSMutableArray,多使用不可變數(shù)組,效率更高.數(shù)組的重點(diǎn)在于查找與修改,靈活使用事半功倍,避免重復(fù)造輪子!

不可變數(shù)組常用方法

//新建一個(gè)數(shù)組
NSArray *arr1 = @[@"11",@"22",@"33"]; //語法糖聲明方法
NSArray *arr2 = [[NSArray alloc] initWithObjects:@0, @1, @2, nil];//蠢乎乎的第二種聲明方法,誰會(huì)用呢?
//獲取數(shù)組長度,為什么要用NSUInteger 你還記得嗎? 其實(shí)用int NSInteger 也是可以的,不過浪費(fèi)了變量空間的分配
NSUInteger cout = [arr1 count];

//獲取某個(gè)位置的數(shù)組,請(qǐng)做好判斷,避免訪問到不存在的下標(biāo)
 id obj = arr[2]; //程序都是從0開始表示第一位的,[2]表示第三個(gè)位置
 id obj = [arr1 objectAtIndex:2]; //同上一樣的效果

//判斷某個(gè)對(duì)象是否存在
 BOOL result = [arr1 containsObject:@"11"]; 
// /取得數(shù)組的首尾元素,很好用有沒有,ios 早期版本還不支持lastObject這個(gè)方法,現(xiàn)在你處在一個(gè)好的時(shí)代.
    id obj = [arr1 lastObject]; //取得數(shù)組的最后一個(gè)元素
    id obj = [arr1 firstObject];// 取得數(shù)組的第一個(gè)元素

// componentsSeparatedByString,以某個(gè)字符分割字符串,返回一個(gè)數(shù)組
    NSString *s = @"今天*我*休息";
    NSArray *arr2 = [s1 componentsSeparatedByString:@"*"];//返回@[@"今天",@"我",@"休息"]
    
//將數(shù)組中元素用某個(gè)字符串拼接起來:componentsJoinedByString,返回一個(gè)字符串類型
    NSArray *arr = @[@"小米",@"華為",@"聯(lián)想"].
    NSString *newString = [arr componentsJoinedByString:@"*"];//返回@"小米,華為,聯(lián)想"

可變數(shù)組常用方法

//新建一個(gè)數(shù)組
NSMutableArray<NSString*> *mArr = = @[@"11",@"22",@"33"].mutableCopy; //語法糖聲明方法,聲明一個(gè)帶有初始元素的可變數(shù)組
NSMutableArray<NSString*> *mArr = [[NSMutableArray alloc] init]; //常用方法

注:<NSString*>表示數(shù)組內(nèi)都為NSString類型, 不可變數(shù)組與可變數(shù)組都可以這樣表示,在遍歷或者調(diào)用內(nèi)部元素的方法時(shí)ide能提示出對(duì)應(yīng)方法~

//添加元素
[marr addObject:@"123"];
//刪除元素
[mArr removeObject:@"123"];//當(dāng)運(yùn)用數(shù)組等的時(shí)候 運(yùn)用removeObject移除對(duì)象的時(shí)候事實(shí)上這些集合內(nèi)部是有一個(gè)判斷的;這個(gè)判斷是基于方法- (BOOL)isEqual:(id)object;的  而這個(gè)方法是判斷內(nèi)容是否相同。所以只要數(shù)組或者集合中有相同的元素,而你所要移除的對(duì)象正好在數(shù)組或者集合中有兩個(gè)或者兩個(gè)以上的時(shí)候,這些對(duì)象都將被移除!
所以如果
NSString *a = @"123";
NSString *b = @"123";
NSMutableArray *mArr =  @[@"1",@"2",a,b].mutableCopy;
[mArr removeObject:b];
a和b都會(huì)被移除,
使用: 
[mArr removeObjectIdenticalTo:a];//根據(jù)地址來移除元素
a和b還是都會(huì)被移除
因?yàn)?
(lldb) p a
(__NSCFConstantString *) $0 = 0x00000001027200c0 @"123"
(lldb) p b
(__NSCFConstantString *) $1 = 0x00000001027200c0 @"123"
a 和 b只要字符串內(nèi)容相同都指向同一個(gè)地址喲!!!!!!!!!!!!!
所以只移除a 或者只移除 b 需要你的思考,怎么做到呢?????
//改
mArr[1] = @"456";  //數(shù)組的第二個(gè)元素改為456 ,
[mArr setObject:@"456" atIndexedSubscript:1];//效果同上
//遍歷
[mArr enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
      //obj 為當(dāng)前遍歷到的對(duì)象
      //idx 為遍歷的位置 從0開始哦
      //stop 為是否有下一次循環(huán)  用 *stop = YES 來停止
 }];

注意:
跳出循環(huán)的坑:
1 只用 *stop = YES; 表示沒有下一次循環(huán)了,這次block"全部"執(zhí)行完就結(jié)束了.
2只用 return;表示這次block就到這,進(jìn)入下一次循環(huán).

此外還有遍歷數(shù)組的刪除問題,邊循環(huán)邊刪除會(huì)出現(xiàn)遍歷跳過后一條的情況. 因?yàn)閯h除元素后,后面的元素下標(biāo)會(huì)都減一,后面的元素跑到了你刪除元素的位置,下一次遍歷就跑到了下下個(gè)元素了. 有沒有暈啊~哈哈

//使用反向遍歷來解決
- (void)enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block;

字典類型介紹

字典在很多語言里也叫map ,也有叫帶鍵值對(duì)的數(shù)組.叫哈希表更高端一些,是根據(jù)key來設(shè)置和訪問值的數(shù)據(jù)結(jié)構(gòu).很常用哦~

//初始化
NSDictionary *dic=@{@"name":@"aaa",@"age":@111};   
 
//@"name" @"age" 表示key
//@"aaa"  @111 表示為對(duì)應(yīng)的值

注: 字典里也是只能放對(duì)象類型 所以 放@111是可以的,111是不允許的.
nil 也不被允許 如果你塞入的變量可能為nil 用name?:@""來替代
?: 為三元運(yùn)算符
NSString *str = (b==1?@"123":@"456") 表示 b等于1 的話 str 就賦值 @"123",否則賦值@"456"
NSString *str = (b?:@"456")表示 b有值 的話 str 就賦值b,否則賦值@"456"

 //分別獲取所有的鍵, 值

    NSLog(@"%@",dic.allKeys);

    NSLog(@"%@",dic.allValues);

    //獲取字典鍵值對(duì)總數(shù)

    NSLog(@"%d",(dic.count));

    //字典遍歷,快速枚舉

    for (id key in dic) {

        id value=[dic objectForKey:key];

        NSLog(@"%@:%@",key,value);

    }

for (id key in dic) 為一種快速遍歷方法,適用于字典和數(shù)組,如果你只是想簡單的把內(nèi)容都取一遍,這個(gè)方法值得使用.

NSMutableDictionary 可變字典介紹

//創(chuàng)建一個(gè)nsmutabledictionary
    NSMutableDictionary *mutableDictionary=[NSMutableDictionary new];
    [mutableDictionary setObject:@"shenyue" forKey:@"name"];
    [mutableDictionary setObject:@21 forKey:@"age"];
    
    //得到詞典中的所有key
    NSEnumerator *enumeratorkey=[mutableDictionary keyEnumerator];
    for (NSObject *obj in enumeratorkey) {
        NSLog(@"key為:%@",obj);
        NSLog(@"通過key找到value值為:%@",[mutableDictionary objectForKey:obj]);
    }
    
    //刪除其中一個(gè)key
    [mutableDictionary removeObjectForKey:@"name"];
    NSLog(@"刪除name的key以后值:%@",mutableDictionary);
    
    [mutableDictionary removeAllObjects];
    NSLog(@"刪除所有以后,可變?cè)~典個(gè)數(shù)為%ld",[mutableDictionary count]);
    

以上為數(shù)據(jù)類型的簡單介紹,工作中最多碰到的就是這些,后面還會(huì)深入介紹其他類型.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。