1. 程式人生 > >IOS開發之OC學習筆記(中)

IOS開發之OC學習筆記(中)

  • 該筆記源自本人對一個網路視訊的學習
  • 如有侵權,請聯絡本人刪除。
  • 都是比較基礎的OC知識,中高階開發者可以忽略本文
  • 很多重要內容在程式碼註釋中

1. Foundation-結構體

用法參考:

NSRange range = NSMakeRange(8, 10);
CGPoint p = NSMakePoint(10, 9);
NSPoint p = CGPointMake(8, 9);
NSSize size = NSMakeSize(90, 80);
CGSize size = CGSizeMake(10, 8);
NSRect rect = = NSMakeRect(10, 10, 80, 80);


CGRect rect = CGRectMake(8, 9, 10, 90);
型別列印方式:NSLog(@”%@”, NSStringFromRect(rect));

2. Foundation-NSString

NSString的建立

// 這種方式創建出來的字串是不需要釋放的
NSString *str1 = @"A String!";

NSString *str2 = [[NSString alloc] init];
str2 = @"A String!";
[str2 release];

//將c語言的字元轉NSString
NSString *str4 = [[NSString
alloc] initWithUTF8String:"A String!"]; [str4 release]; str4 = [NSString stringWithUTF8String:"A String!"]; str5 = [NSString stringWithFormat:@"My age is %i and height is %.2f", 19, 1.55f];

從檔案、網路讀取文字

NSString *path = @"/Users/apple/Desktop/test.txt";
// 這個方法已經過期,不能解析中文
// NSString *str1 = [NSString stringWithContentsOfFile:path];
// 定義一個NSError變數 NSError *error; // 指定字串編碼為UTF-8: NSUTF8StringEncoding NSString *str1 = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; if (error == nil) { // 沒有錯誤資訊 NSLog(@"讀取檔案成功:%@", str1); } else { NSLog(@"讀取檔案失敗:%@", error); } NSURL *url = [NSURL URLWithString:@"file:///Users/apple/Desktop/test.txt"]; NSString *str2 = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil]; NSLog(@"%@", str2); NSURL *url2 = [NSURL URLWithString:@"http://www.baidu.com"]; NSString *str3 = [NSString stringWithContentsOfURL:url2 encoding:NSUTF8StringEncoding error:nil]; NSLog(@"%@", str3);

字串的匯出

NSString *str = @"123456我是字串!!!!";
// 如果檔案不存在,會自動建立檔案
// 如果資料夾不存在,會直接報錯
NSString *path = @"/Users/apple/Desktop/abc.txt";

NSError *error;
// 編碼指定錯誤也會報錯
// YES代表要進行原子性操作,也就是會建立一箇中間的臨時檔案
[str writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (error) {
    // [error localizedDescription]會返回主要的錯誤資訊
    NSLog(@"寫入失敗:%@", [error localizedDescription]);//???
} else {
    NSLog(@"寫入成功");
}

大小寫轉換

NSString *str = @"GuangDong";
NSLog(@"大寫:%@", [str uppercaseString]);
NSLog(@"小寫:%@", [str lowercaseString]);
// 首字母變大寫,其他字母變小寫
NSLog(@"首字母變大寫:%@", [@"aGE" capitalizedString]);

字串的比較

// 檢測字串的內容是否相同
BOOL result = [@"abc" isEqualToString:@"abc"];
NSLog(@"%i", result);

NSLog(@"'a' =%i ,'A' = %i", 'a','A');
//'a' =97 ,'A' = 65

// NSOrderedAscending  右邊的字串比左邊大
// NSOrderedSame  兩個字串的內容相同
// NSOrderedDescending  左邊的字串比右邊的大
NSComparisonResult result2 = [@"abc" compare:@"Abc"];
if (result2 == NSOrderedSame) {
    NSLog(@"兩個字串的內容相同");
} else if (result2 == NSOrderedAscending) {
    NSLog(@"右邊 > 左邊");
} else if (result2 == NSOrderedDescending) {
    NSLog(@"右邊 < 左邊");
}
//右邊 < 左邊

字串的搜尋

NSString *str = @"123456456.txt";

NSLog(@"是否以22開頭:%i", [str hasPrefix:@"22"]);//0
NSLog(@"是否以txt結尾:%i", [str hasSuffix:@"txt"]);//1

// 搜尋字串
NSRange range = [str rangeOfString:@"456"];
// range.length == 0
if (range.location == NSNotFound) {
    NSLog(@"不能找到");
} else {
    NSLog(@"找到的範圍是:%@", NSStringFromRange(range));//{3, 3}
}

// 從尾部開始搜尋字串
range = [str rangeOfString:@"456" options:NSBackwardsSearch];
NSLog(@"從尾部開始搜尋:%@", NSStringFromRange(range));//{6, 3}

// 指定範圍進行搜尋
range = [str rangeOfString:@"456" options:NSBackwardsSearch range:(NSMakeRange(2, 6))];
NSLog(@"指定範圍進行搜尋:%@", NSStringFromRange(range));//{3, 3}

字串的擷取

NSString *str = @"123456";

// 從索引3開始擷取到尾部(包括3)
NSLog(@"%@", [str substringFromIndex:3]);//456

// 從頭部開始擷取到索引3之前(不包括3)
NSLog(@"%@", [str substringToIndex:3]);//123

// 指定範圍進行擷取
NSRange range = NSMakeRange(2, 3);
NSLog(@"%@", [str substringWithRange:range]);//345

NSString *str2 = @"a-b-c-d-5";
NSArray *array = [str2 componentsSeparatedByString:@"-"];
NSLog(@"%@", array);//(a,b,c,d,5)

NSString *str3 =  [array objectAtIndex:0];
NSLog(@"%@", str3);//a

與路徑相關

// 快速建立一個自動釋放的陣列
NSMutableArray *components = [NSMutableArray array];
[components addObject:@"Users"];
[components addObject:@"MJ"];
[components addObject:@"Desktop"];
// 將陣列中的所有字串拼接成一個路徑
NSString *path = [NSString pathWithComponents:components];
NSLog(@"%@", path);//Users/MJ/Desktop

// 將路徑分解成一個數組
NSArray *cmps = [path pathComponents];
NSLog(@"%@", cmps);//(Users,MJ,Desktop)

// path是一個字串常量,是不可變的
path = @"/users/mj/test";
// 判斷是夠為絕對路徑(依據是前面有無/)
NSLog(@"%i", [path isAbsolutePath]);//1
NSLog(@"最後一個目錄:%@", [path lastPathComponent]);//test
// 刪除最後一個目錄
NSLog(@"%@", [path stringByDeletingLastPathComponent]);///users/mj
// 在最後面拼接一個目錄
NSLog(@"%@", [path stringByAppendingPathComponent:@"abc"]);///users/mj/test/abc

拓展名處理

NSString *str = @"/User/MJ/test.txt";

NSLog(@"拓展名:%@", [str pathExtension]);//txt
// 刪除拓展名
NSLog(@"%@", [str stringByDeletingPathExtension]);///User/MJ/test
// 新增拓展名
NSLog(@"%@", [@"abc" stringByAppendingPathExtension:@"mp3"]);//abc.mp3

其他用法

//NSString 轉int
NSString *str = @"12";
int a = [str intValue];
NSLog(@"%i", a);//12

// 計算字數,不是計算字元數
NSLog(@"length=%zi", [@"我是字串123" length]);//length=8

// 取出對應的字元
unichar c = [@"abc" characterAtIndex:0];
NSLog(@"%c", c);

// 返回C語言中的字串
const char *s = [@"abc" UTF8String];
NSLog(@"%s", s);//abc

3. Foundation-NSMutableString

可變字串的建立

// 預先分配10個字數的儲存空間
NSMutableString *str = [[NSMutableString alloc] initWithCapacity:10];

//this is ok
NSMutableString *str = [[NSMutableString alloc]init];

// 設定字串內容
[str setString:@"1234"];

// 拼接一個字串
[str appendString:@"567"];
// 拼接字串
[str appendFormat:@"age is %i and height is %.2f", 27, 1.55f];
//1234567age is 27 and height is 1.55

// 替換字串
NSRange range = [str rangeOfString:@"height"];
//NSRange range = NSMakeRange(7, 3);
[str replaceCharactersInRange:range withString:@"no"];
//1234567age is 27 and no is 1.55

// 插入字串
[str insertString:@"abc" atIndex:2];
//12abc34567age is 27 and no is 1.55

// 刪除字串
range = [str rangeOfString:@"age"];
[str deleteCharactersInRange:range];

NSLog(@"%@", str);
//12abc34567 is 27 and no is 1.55

// 釋放物件
[str release];

4. Foundation-NSArray

建立一個數組

// 建立一個空的陣列
NSArray *array = [NSArray array];

// 建立有1個元素的陣列
array = [NSArray arrayWithObject:@"123"];

// 建立有多個元素的陣列
array = [NSArray arrayWithObjects:@"a", @"b", @"c", nil]; //count = 3

int count = [array count];
// count = array.count;
NSLog(@"%i", count);

陣列的簡單使用

NSObject *obj = [[NSObject alloc] init];
NSArray *array = [NSArray arrayWithObjects:@"a", @"b", @"c" , obj, nil];
// 判斷是否包含了某個元素
if ([array containsObject:@"a"]) {
    NSLog(@"包含了字串a");
}

NSString *last = [array lastObject];
NSLog(@"last=%@", last);//

NSString *str = [array objectAtIndex:1];
NSLog(@"%@", str);

int index = [array indexOfObject:@"c"];
NSLog(@"index=%i", index);

[obj release];

陣列的記憶體管理

Student *stu1 = [[Student alloc] init];
Student *stu2 = [[Student alloc] init];
Student *stu3 = [[Student alloc] init];

NSLog(@"stu1:%zi", [stu1 retainCount]);//1

// 當把一個物件塞進陣列中時,這個物件的計數器會加1,也就是說陣列會對它做一次retain操作
NSArray *array = [[NSArray alloc] initWithObjects:stu1, stu2, stu3, nil];

NSLog(@"stu1:%zi", [stu1 retainCount]);//2

NSLog(@"count=%zi", array.count);//3

[stu1 release];//1
[stu2 release];
[stu3 release];

// 陣列被銷燬的時候,會對內部的所有元素都做一次release操作
[array release];//0

給數組裡面的元素髮送訊息

Student *stu1 = [Student student];
Student *stu2 = [Student student];
Student *stu3 = [Student student];

NSArray *array = [NSArray arrayWithObjects:stu1, stu2, stu3, nil];
// 讓數組裡面的所有物件都呼叫test方法
 [array makeObjectsPerformSelector:@selector(test)];
// 讓數組裡面的所有物件都呼叫tes2t方法,並傳遞一個
[array makeObjectsPerformSelector:@selector(test2:) withObject:@"123"];

遍歷陣列

Student *stu1 = [Student student];
NSArray *array = [NSArray arrayWithObjects:stu1, @"1", @"2", @"3", nil];
//方法1
int count = array.count;
for (int i = 0; i<count; i++) {
    // id == void *
    id obj = [array objectAtIndex:i];
    NSLog(@"%i-%@", i, obj);
}
//方法2
// 快速遍歷
int i =0;
for (id obj in array) {
    NSLog(@"%i-%@", i, obj);
    i++;
}
//方法3
[array enumerateObjectsUsingBlock:
 ^(id obj, NSUInteger idx, BOOL *stop) {
    NSLog(@"%i-%@", idx, obj);

     // 如果索引為1,就停止遍歷
     if (idx == 1) {
         // 利用指標修改外面BOOL變數的值
         *stop = YES;
     }
}];
//方法3輸出:
//0-<Student: 0x100102e40>
//1-1

//方法4
// 獲取陣列的迭代器
// NSEnumerator *enumerator = [array objectEnumerator];
// 反序迭代器(從尾部開始遍歷元素)
NSEnumerator *enumerator = [array reverseObjectEnumerator];

// allObjects是取出沒有被遍歷過的物件
NSArray *array2 = [enumerator allObjects];
NSLog(@"array2:%@", array2);

// 獲取下一個需要遍歷的元素
id obj = nil;
while (obj = [enumerator nextObject]) {
    NSLog(@"obj=%@", obj);
}

派生出新的陣列

NSArray *array = [NSArray arrayWithObjects:@"1", @"2", nil];

NSArray *array2 = [array arrayByAddingObject:@"3"];

NSArray *array3 = [array arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:@"4", @"5", nil]];

NSLog(@"array:%@", array);//(1,2)
NSLog(@"array2:%@", array2);//(1,2,3)
NSLog(@"array3:%@", array3);//(1,2,4,5)

NSArray *array4 = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", nil];
NSRange range = NSMakeRange(1, 2);
NSArray *array5 = [array4 subarrayWithRange:range];
NSLog(@"array5:%@", array5);//(2,3)

陣列的其他用法

NSArray *array = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", nil];
// 1-2-3-4
// 利用分隔符-拼接所有的陣列元素
NSString *str = [array componentsJoinedByString:@"-"];
NSLog(@"%@", str);

// 將一個數組寫入檔案(生成的是一個xml檔案)
NSString *path = @"/Users/apple/Desktop/array.xml";
[array writeToFile:path atomically:YES];

path = @"/Users/apple/Desktop/array.txt";
//上面寫入的xml檔案,此處也可以直接讀取
// 從檔案中讀取陣列內容(檔案有嚴格的格式要求),格式如下
//<array>
//  <string>1</string>
//  <string>2</string>
//  <string>3</string>
//  <string>4</string>
//</array>

NSArray *array2 = [NSArray arrayWithContentsOfFile:path];
NSLog(@"array2:%@", array2);

陣列排序

  • 排序1
NSArray *array = [NSArray arrayWithObjects:@"2", @"3", @"1", @"4", nil];
// 返回一個排好序的陣列,原來陣列的元素順序不會改變
// 指定元素的比較方法:compare:
// compare two NSDecimalNumbers
NSArray *array2 = [array sortedArrayUsingSelector:@selector(compare:)];
NSLog(@"array2:%@", array2);//(1,2,3,4)
  • 排序2、3
Student *stu1 = [Student studentWithFirstname:@"MingJie" lastname:@"Li"];
Student *stu2 = [Student studentWithFirstname:@"LongHu" lastname:@"Huang"];
Student *stu3 = [Student studentWithFirstname:@"LianJie" lastname:@"Li"];
Student *stu4 = [Student studentWithFirstname:@"Jian" lastname:@"Xiao"];
NSArray *array = [NSArray arrayWithObjects:stu1,stu2,stu3, stu4, nil];

方法1
// 指定排序的比較方法
NSArray *array2 = [array sortedArrayUsingSelector:@selector(compareStudent:)];
//compareStudent 是什麼,見下一個程式碼塊

//方法2
// 利用block進行排序
NSArray *array2 = [array sortedArrayUsingComparator:
 ^NSComparisonResult(Student *obj1, Student *obj2) {
     // 先按照姓排序
     NSComparisonResult result = [obj1.lastname compare:obj2.lastname];
     // 如果有相同的姓,就比較名字
     if (result == NSOrderedSame) {
         result = [obj1.firstname compare:obj2.firstname];
     }

     return result;
}];

NSLog(@"array2:%@", array2);
//("[Huang LongHu-(null)]","[Li LianJie-(null)]","[Li MingJie-(null)]","[Xiao Jian-(null)]")
其中compareStudent是Student的一個方法,如下:
- (NSComparisonResult)compareStudent:(Student *)stu {
    // 先按照姓排序
    NSComparisonResult result = [self.lastname compare:stu.lastname];
    // 如果有相同的姓,就比較名字
    if (result == NSOrderedSame) {
        result = [self.firstname compare:stu.firstname];
    }

    return result;
}
  • 排序4
Student *stu1 = [Student studentWithFirstname:@"MingJie" lastname:@"Li" bookName:@"book1"];
Student *stu2 = [Student studentWithFirstname:@"LongHu" lastname:@"Huang" bookName:@"book2"];
Student *stu3 = [Student studentWithFirstname:@"LianJie" lastname:@"Li" bookName:@"book2"];
Student *stu4 = [Student studentWithFirstname:@"Jian" lastname:@"Xiao" bookName:@"book1"];
NSArray *array = [NSArray arrayWithObjects:stu1,stu2,stu3, stu4, nil];

// 1.先按照書名進行排序
// 這裡的key寫的是@property的名稱
NSSortDescriptor *bookNameDesc = [NSSortDescriptor sortDescriptorWithKey:@"book.name" ascending:YES];
// 2.再按照姓進行排序
NSSortDescriptor *lastnameDesc = [NSSortDescriptor sortDescriptorWithKey:@"lastname" ascending:YES];
// 3.再按照名進行排序
NSSortDescriptor *firstnameDesc = [NSSortDescriptor sortDescriptorWithKey:@"firstname" ascending:YES];
// 按順序新增排序描述器
NSArray *descs = [NSArray arrayWithObjects:bookNameDesc, lastnameDesc, firstnameDesc, nil];

NSArray *array2 = [array sortedArrayUsingDescriptors:descs];

NSLog(@"array2:%@", array2);
//("[Li MingJie-book1]","[Xiao Jian-book1]","[Huang LongHu-book2]","[Li LianJie-book2]")

5. Foundation-NSMutableArray

用法如下

NSMutableArray *array = [NSMutableArray arrayWithObject:@"1"];
// 新增元素
[array addObject:@"2"];
[array addObject:@"3"];

//移除元素
[array removeObject:@"2"];
[array removeLastObject];
[array removeAllObjects];

//替換元素
[array replaceObjectAtIndex:1 withObject:@"4"];

//排序
[array sortUsingSelector:@selector(compare:)];
//此處array發生變化,區別NSArray

NSMutableArray的記憶體管理

NSMutableArray *array = [[NSMutableArray alloc] init];

Student *stu1 = [[Student alloc] init];// stu1:1
stu1.age = 10;

Student *stu2 = [[Student alloc] init];// stu2:1
stu2.age = 20;

// 對被新增的元素做一次retain操作,計數器+1
[array addObject:stu1]; // stu1:2
[array addObject:stu2]; // stu2:2

NSLog(@"add->stu1:%zi", [stu1 retainCount]);

// 對被刪除的元素做一次release操作,計數器-1
[array removeObject:stu1]; // stu1:1

NSLog(@"remove->stu1:%zi", [stu1 retainCount]);

// 釋放學生
[stu1 release]; // stu1:0
[stu2 release]; // stu2:1

// 當陣列被釋放的時候,會對所有的元素都做一次release操作
[array release]; // stu2:0