UIImageView * imgv=[[UIImageView alloc]init];
imgv是指針,指針指向的是對象姿染。
[[UIImageView alloc]init]; 創(chuàng)建了一個對象
imgv = 寫在前面利耍,等于把imgv指向了那個對象。所以imgv是指針
而對象藏在內(nèi)存的某個角落里面盔粹,需要通過指針來訪問
指針指向了對象在內(nèi)存中的一個地址 通過這個指針找到內(nèi)存中的對象 以后寫代碼對指針進行操作就相當(dāng)于對指針指向的對象進行操作
通過指針來找到對象而不是表示對象。
%p
作用:輸出內(nèi)存地址
使用:
NSString *name = @"xxxx";
NSLog(@"%p",name);
NSLog(@"%p",&name);
結(jié)果:
解釋:
1程癌、前者是字符串 "xxxx" 內(nèi)存首地址
2舷嗡、后者是指針name 內(nèi)存首地址
二級指針
解釋:指向指針的指針
舉例:NSString** 表示NSString類型的二級指針
作用:可以通過*號來訪問、操作內(nèi)存嵌莉;訪問的過程為:二級指針訪問一級指針的內(nèi)容进萄,我們知道,一級指針存的是地址锐峭,系統(tǒng)會根據(jù)該地址訪問一級指針指向的內(nèi)容中鼠,這個過程也叫間接訪問
使用: (MRC模式下,ARC模式下不支持定義變量)
1沿癞、訪問變量內(nèi)容
NSString *name = @"xxxx";
NSString** pointer = &name;
NSLog(@"%@",name); // 一級指針直接訪問內(nèi)容
NSLog(@"%@",*pointer); // 二級指針間接訪問內(nèi)容
NSLog(@"%p",&name); // 一級指針的內(nèi)存首地址
NSLog(@"%p",pointer); // 二級指針指向一級指針地址
結(jié)果:
2援雇、修改變量內(nèi)容
NSString *name = @"xxxx";
NSLog(@"修改前:%@",name);
[self getNewName:&name];
NSLog(@"修改后:%@",name);
// 修改name方法
-(void)getNewName:(NSString**)nameNew{
*nameNew = @"LOLITA0164";
}
結(jié)果:
解釋:
二級指針nameNew存的是一級指針name的地址,*nameNew 間接訪問了字符串 “xxxx” 的內(nèi)存地址椎扬, *nameNew = @"LOLITA0164"; 最終結(jié)果是修改了 “xxxx”的內(nèi)存地址的內(nèi)容惫搏,因此輸出結(jié)果為“LOLITA0164”
對比
NSString *name = @"xxxx";
NSLog(@"修改前:%@",name);
[self getNewName2:name];
NSLog(@"修改后:%@",name);
-(void)getNewName2:(NSString*)nameNew{
nameNew = @"lolita";
}
結(jié)果:
解釋:
和之前的例子不同具温,這個例子中,一級指針nameNew指向了內(nèi)容為“xxxx”的地址筐赔,這個地址和一級指針name指向完全不同铣猩,屬于兩個不同的地址,所以修改nameNew指向的內(nèi)容并不會影響到name指向的內(nèi)容
應(yīng)用
那么知道了二級指針的作用茴丰,那么要怎么應(yīng)用呢达皿?
需求:傳遞處理后的多個參數(shù),而無需返回值
NSString *name = @"xxxx";
NSArray *types = @[@"iOS",@"android"];
[self getNewTypes:&types andNewName:&name];
NSLog(@"\n處理后\n類型->%@ --- 名稱->%@",types,name);
// 處理方法
-(void)getNewTypes:(NSArray**)typesNew andNewName:(NSString**)name{
*name = @"LOLITA";
*typesNew = @[@"iOS",@"android",@"windows"];
}
結(jié)果
說明贿肩,因為是操作內(nèi)存地址峦椰,所以無需返回值
補充:修改自定義數(shù)據(jù)模型
-(void)getNewPerson:(Person**)p{
Person *newP = *p;
newP.age = 26;
}
注意??
在MRC下,二級指針類型定義為屬性尸曼、成員變量或者參數(shù)都是可行的
在ARC下们何,二級指針類型則不能定義為屬性或成員變量,但是可以作為參數(shù)傳遞
擴展
關(guān)于傳遞多個返回值問題控轿,有以下幾個解決方案
返回多值
1冤竹、字符串 ---> 如果是字符串類型,可拼接成一個字符返回字符串
2茬射、數(shù)組 (必須是同種數(shù)據(jù)類型)
3鹦蠕、字典 (必須知道對應(yīng)key)
4、數(shù)據(jù)模型 ---> 可構(gòu)建多種數(shù)據(jù)類型在抛,讀取方便钟病,優(yōu)于前三種,缺點是需要自定義數(shù)據(jù)模型
傳遞方式
1刚梭、主線程
a肠阱、return
b、** (二級指針)2朴读、 異步線程(當(dāng)處理結(jié)果時長未知時使用)
a屹徘、block
關(guān)于block傳遞值的例子:
-(void)getPersonInfoWithType:(NSInteger)type result:(void(^)(Person *p,id error))block{
Person *p = nil;
NSString *errorInfo = nil;
if (type==0) {
p = [Person new];
p.age = 10; // 一些耗時操作,例如數(shù)據(jù)請求等
p.name = @"xiaoming";
}else if (type==1){
p = [Person new];
p.age = 25; // 一些耗時操作衅金,例如數(shù)據(jù)請求等
p.name = @"LOLITA0164";
}else{
errorInfo = @"沒有這種類型";
}
if (block) {
block(p,errorInfo);
}
}
獲取數(shù)據(jù)
[self getPersonInfoWithType:1 result:^(Person *p, id error) {
if (error) {
NSLog(@"%@",error);
}else{
NSLog(@"name:%@,age:%ld",p.name,p.age);
}
}];
結(jié)果
說明:我們通過傳遞一個類型噪伊,獲取到了類型為1的Person數(shù)據(jù),通常我們使用block這種方式來獲取數(shù)據(jù)氮唯,這樣不會阻塞線程鉴吹,并在拿到數(shù)據(jù)時,操作UI更新