第八天視頻課程:
認識字符串 NSString
NSString是一個Unicode編碼揍瑟、16位字符的字符序列卖宠。
NSString被定義為類,引用類型碉怔,拷貝是具有引用語法逾滥。
初始化方法:
NSString *str1 = @"Hello World!"; \\字面量初始化,必須加@符號表示支持NSString是OC的字符串峰档。
NSString *str2 =[[NSString alloc]initWithCString:"Hello World!" encoding:NSUTF8StringEncoding]; \\初始化器,分配內存,傳遞C語言的字符串寨昙,進行編碼讥巡。
NSString *str3 =[NSString stringWithCString:"Hello World!" encoding:NSUTF8StringEncoding];工廠方法,工廠方法stringWithCString是一個類方法,返回了一個類對象舔哪。
NSString擁有恒定性(初始化之后值就不可以改變)尚卫,所有的操作無法更改字符串本身,如有更改尸红,都是返回新值的形式。
NSString擁有共享機制(由于NSString擁有恒定性刹泄,所以用字面量初始化方法(初始化器和工廠方法是動態(tài)創(chuàng)建方法這里沒有共享機制效果)初始化的兩個字符串的內同完全相同的話外里,這兩個字符串將指向同一塊堆空間,即使用同一塊內存空間)特石,引用技術管理對其有特殊的管理規(guī)則盅蝗。
偽更改:返回新字符串
str1 = [str1 stringByAppendString:@''Yes!"]; //這句語句會申請一段新的內存,復制在原來str1字符串的內容姆蘸,再在后面添加Yes墩莫!這幾個字符,返回新的內存地址逞敷。原來的str1 地址指向的內存內容不變狂秦。
字符串之間判斷相等:
如果要判斷兩個字符串的值是否相等要使用isEqualToString方法: [str1isEqualToString: str2] //比較str1和str2里面的值是否相等。如比較兩個字符串指向的內存是否相等(指針是否相等)就用:str1 == str2來判斷這兩個字符串是否指向了同一塊內存推捐。
認識NSMutableString
NSMutableString具有可變性裂问,NSString具有恒定性。
NSMutableString為NSString的子類
由于NSMutableString是NSString的子類可以吧一個NSMutableString類對象賦值給一個NSString類對象:
NSString *str5 = mustr1;
[mustr1 appendString:@"Very Good!"];
執(zhí)行完上述操作將發(fā)現(xiàn),NSString類對象str5也跟隨NSMutableString類對象mustr1發(fā)生了改變堪簿,這樣就違背了NSString的恒定性痊乾,這是一個類似漏洞的東西,以后要將NSMutableString類中的內容復制到NSString不可以直接賦值椭更,而是要用stringCopy方法哪审。
NSMutableString不具有共享機制,NSString具有共享機制虑瀑。
NSMutableString并不是在原有內存上直接增長湿滓,而是重新分配一個更大或者更小的緩存容量存放字符
NSMutableString字符串初始化后,會分配一個緩存容量(capacity),其長度一般大于實際的字符串數(shù)量缴川。當字符串增長時茉稠,如實際需求大于capacity,其capacity會以二倍的方式指數(shù)增長,伴隨的代價:
分配新的堆內存 2*capacity
將原來堆內存上的內容拷貝到新內存
釋放原來堆內存
最佳實踐:估計好capacity把夸,預先分配好一定容量而线,避免以后capacity的增長。
NSMutableString *mustr3 = [NSMutableString stringWithCapacity:100]; //在用工廠方法申請NSMutableString類對象時預留100個字符的緩存容量(capacity)恋日。
字符串的長用方法
NSString:
訪問字符串:
獲取字符串字符:[str1 characterAtIndex:i];
字符串長度:[str1 length];
字面量:
大小寫轉換 :str1 = str1.uppercaseString;
str1 = str1.lowercaseString;
str1 = str1.capitalizedString;
查詢字符串:
定位子串:NSRange range = [str1 rangOfString:@"Hello"];
NSLog(@"location:%lu, length:%lu, range.location, rang.length);
獲取子串:NSString *substr = [str1 substringFromIndex:6];
是否包含子串:BOOL yOrN = [str1 hasPrefix:@"Hello"];
查詢字符集:rangOfCharacterFromSet:
其他操作:
比較字符串:isEqualToString:
替換字符串:stringByReplacingOccurrencesOfString: withString
分解字符串:componentsSeparatedByCharactersInSet:
NSMutableString:
添加字符串:[mustr3 appendString:@"Hello Objective"];
刪除字符串:[mustr3 insertString:@"-C" atIndex:mustr3.length];
修改字符串:[mustr3 setString:@"Hi Objective"];
NSRange replaceRange = NSMakeRange(0, 2);
[mustr3 relpaceCharactersInRange:replaceRange withString:@"Hello"];
NSRange deleteRange = NSMakeRange(5, 10);
[mustr3 deleteCharactersInRange:deleteRange];
第九天視頻課程:
認識數(shù)組
數(shù)組是一個有序的元素序列膀篮,支持隨機存取。索引從0開始岂膳,索引訪問越界會拋出運行時異常誓竿。注意與C語言數(shù)組不同。
NSArray被定義為類谈截,引用類型筷屡,拷貝時具有引用語義。
NSArray的初始化:
NSArray *array1 = [NSArray arrayWithObjects:@"Shanghai",@"Beijing",@"New York",@"Paris",nil]; //工廠方法初始化簸喂,最后要加nil,表示數(shù)組的結束毙死。
NSArray *array2 = [[NSArray alloc]initWithObjects:@"Shanghai",@"Beijing",@"New York",@"Paris",nil]; //分配內存+初始化器,最后也要加nil做結束符
NSArray *array3 = @[Shanghai",@"Beijing",@"New York",@"Paris"]; //直接使用字面常量喻鳄,在最前面要加@,結束時不需要加nil
NSArray的元素必須是對象扼倘,即NSObject的子類:
NSString *text = @"Panda"; //字符串對象
如為基本數(shù)值類型,須用NSNumber(繼承于NSValue的類)封裝為對象后除呵,才能放入數(shù)組中再菊。
NSInteger number = 100; // NSInteger是基本數(shù)值類型(整數(shù)),不是一個類
NSNumber *numberObject1 = [NSNumber numberWithInteger:number]; //使用NSNumber將NSInteger包裝為對象
NSNumber *numberObject2 = @300u; //使用字面常量初始化
如為C語言結構類型(struct)颜曾,須用NSValue封裝為對象類型后纠拔,才能放入數(shù)組中。
Point point; //Point是一個結構類型(struct)
point.h = 100;
point.v = 200;
NSValue *pointObject = [NSValue value:&point withObjCType:@encode(Point)]; //使用NSValue將struct包裝為對象
數(shù)組元素可以是不同對象類型泛啸,可能會有類型不安全绿语。
NSNull *nullValue = [NSNull null]; //創(chuàng)建了一個空值類
NSArray *array4 = @[text, numberObject1, numberObject2, pointObject, nullValue ]; //創(chuàng)建的array4數(shù)組中大多的元素都是不同的對象類型
NSArray具有常量性:數(shù)組的長度和元素指針都不能更改秃症。但指針指向的對象內部可以更改。
BLNPoint *p1=[[BLNPoint alloc] initWithX:10 WithY:20];
BLNPoint *p2=[[BLNPoint alloc] initWithX:20 WithY:40];
BLNPoint *p3=[[BLNPoint alloc] initWithX:30 WithY:60];
BLNPoint *p4=[[BLNPoint alloc] initWithX:40 WithY:80];
NSArray *array5=@[p1,p2,p3,p4];
NSLog(@"array5: %@", array5);
BLNPoint *p5=[[BLNPoint alloc] initWithX:50 WithY:100];
//1. 更改元素長度-----不可以吕粹!
//[array5 addObject:p5];
//2. 更改元素指針-----不可以种柑!
//array5[0]=p5;
//3. 更改指針指向的內容-----可以!
for(int i=0;i
????? BLNPoint *pt = array5[i];
????? pt.x++;
????? pt.y++;
}
NSLog(@"array5: %@", array5);
數(shù)組遍歷
//快速枚舉(fast enumeration),直接訪問內存匹耕,優(yōu)化索引檢查聚请,快5-10倍
for ( BLNPoint* point in array5)
{
????? point.x++;
????? point.y++;
}
//迭代器模式(NSEnumerator),索引檢查+動態(tài)消息調用
NSEnumerator *enumerator = [array5 objectEnumerator];
BLNPoint* item;
while (item = [enumerator nextObject])
{
????? item.x++;
????? item.y++;
}
//for循環(huán), 索引檢查+動態(tài)消息調用
for (int i=0; i
????? NSLog(@"array5[%d],%@", i, array5[i]);
}
推薦快速枚舉的方法來遍歷數(shù)組稳其,快速枚舉的方法較其他兩種方法簡化了索引檢查和動態(tài)消息調用的次數(shù)驶赏,效率和性能較高。沒有極特殊的理由不要用后兩種方法來遍歷數(shù)組既鞠。
數(shù)組查找
indexOfObject查找是否存在“值相等”的對象(類型需要實現(xiàn)isEqual)
- (BOOL)isEqual:(id)anObject{ //重寫需要比較類的isEqual方法
? ? ? if (! [anObject isKindOfClass: [BLNPoint class]] ){? //isKindOfClass方法用來查看一個實例是不是屬于某個類
?????????? ?return false;
????? }
BLNPoint* other=anObject;
return (self.x==other.x && self.y==other.y);
}
//開始查找數(shù)組
BLNPoint* target=[[BLNPoint alloc] initWithX:33 WithY:63];
NSUInteger index1=[array5 indexOfObject:target];
//按指針查找
indexOfObjectIdenticalTo查找是否存在“指針相等”的對象
NSUInteger index2=[array5 indexOfObjectIdenticalTo:p3];
數(shù)組排序
不改變原數(shù)組(常量性)煤傍,返回新數(shù)組
NSArray* sortArray1=[array1 sortedArrayUsingSelector:@selector(compare:)]; //由于數(shù)組的常量性,排列后遠數(shù)組不變嘱蛋,必須將返回值賦給一個新的數(shù)組
使用NSMutableArray數(shù)組
NSMutableArray支持更改數(shù)組長度和元素指針蚯姆。為NSArray子類。
NSMutableArray初始化后洒敏,會分配一個緩存容量capacity龄恋,一般大于實際元素數(shù)量,當長度增長時凶伙,如實際需求大于capacity郭毕,其capacity會以近似兩倍的方式指數(shù)增長。(和NSMutableString類似)
伴隨代價:
分配新的堆內存 2*capacity
將原來堆內存上的內容拷貝到新內存
釋放原來堆內存
最佳實踐:估計好capacity函荣,預先分配好一定容量显押,避免以后capacity的增長。
盡量避免使用insertObject: atIndex:和removeObjectAtIndex:等操作傻挂,因為會改變數(shù)組元素序列煮落,涉及大量內存拷貝操作,代價高
NSMutableArray? *muArray1=[NSMutableArray arrayWithObjects:p1,p2,p3,p4, nil];
NSLog(@"before change, muArray1: %@",muArray1);
BLNPoint *p6=[[BLNPoint alloc] initWithX:60 WithY:120];
BLNPoint *p7=[[BLNPoint alloc] initWithX:70 WithY:140];
//修改元素
[muArray1 addObject:p5];
[muArray1 removeObjectAtIndex:2];
[muArray1 insertObject:p6 atIndex:1];
muArray1[0]=p7;? //[muArray1 setObject:p7 atIndexedSubscript:0]; //替換有兩種方法踊谋,前一種方法比較方便
NSLog(@"after change, muArray1: %@",muArray1);
//預估容量
int count=100;?NSMutableArray *muArray2=[NSMutableArray arrayWithCapacity:10];//編程時根據(jù)實際情況合理分配預估容量,盡量不要讓capacity出現(xiàn)不夠用兒擴容旋讹,那樣代價比較大
for (int i=0; i< count; i++) {
????? BLNPoint *pt=[[BLNPoint alloc] initWithX:i*10 WithY:i*20];
????? [muArray2 addObject: pt];
}
認識Set
NSSet是一個無序的集合殖蚕,其存儲的對象不能重復。
NSSet被定義為class沉迹,引用類型睦疫,拷貝時具有引用語義。
常量集合NSSet鞭呕,可變量集合:NSMutableSet:
常量性:長度和元素指針都不能更改蛤育,但指針指向的對象內部可以更改。
創(chuàng)建NSMutableSet時用initWithCapacity提前設置capacity
支持Fast Enumeration和NSEnumerator遍歷,前者較快
NSSet *set1 =?[NSSet setWithObjects:@"Shanghai",@"Beijing",@"New York",@"Paris", nil];
NSLog(@"set1 count: %lu", set1.count);
NSMutableSet *set2 =?[NSMutableSet setWithObjects:@"Shanghai",@"Beijing",@"New York",@"Paris", nil];
[set2 addObject:@"London"];
[set2 addObject:@"Paris"];
[set2 removeObject:@"Beijing"];
NSLog(@"set2 count: %lu", set2.count);
if([set2 containsObject:@"Shanghai"])
{
????? NSLog(@"set2 contains Shanghai");
}
for(NSString* item in set2)
{
????? NSLog(@"%@", item);
}
認識Dictionary
NSDictionary是一個存儲key-value的無序集合瓦糕,key唯一底洗,value可重復。
NSDictionary被定義為class咕娄,引用類型亥揖,拷貝時具有引用語義。
常量集合NSDictionary圣勒,可變量集合:NSMutableDictionary:
常量性:長度和元素指針都不能更改费变,但指針指向的對象內部可以更改。
創(chuàng)建NSMutableDictionary時用initWithCapacity提前設置capacity
支持Fast Enumeration和NSEnumerator遍歷圣贸,前者較快
BLNPoint *p1=[[BLNPoint alloc] initWithX:10 WithY:20];
BLNPoint *p2=[[BLNPoint alloc] initWithX:20 WithY:40];
BLNPoint *p3=[[BLNPoint alloc] initWithX:30 WithY:60];
BLNPoint *p4=[[BLNPoint alloc] initWithX:40 WithY:80];
BLNPoint *p5=[[BLNPoint alloc] initWithX:50 WithY:100];
NSDictionary *dictionary1 = @{
@"Shanghai" : p1,
@"Beijing" : p2,
@"New York" : p3,
@"Paris" : p4};
NSMutableDictionary *dictionary2 = [NSMutableDictionary dictionaryWithObjectsAndKeys:
p1,@"Shanghai",
p2,@"Beijing",
p3,@"New York",
p4,@"Paris",
nil];
NSLog(@"dictionary1 count: %lu", dictionary1.count);
NSLog(@"dictionary2 count: %lu", dictionary2.count);
BLNPoint* result1=[dictionary1 objectForKey:@"Beijing"];
BLNPoint* result2=dictionary1[@"Shanghai"];
NSLog(@"%@", result1);
NSLog(@"%@", result2);
for(NSString* key in dictionary1)
{
????? id object=dictionary1[key];
????? NSLog(@"key:%@, object:%@", key, object);
}
[dictionary2 setObject:p5 forKey:@"London"];
[dictionary2 removeObjectForKey:@"Shanghai"];
NSLog(@"dictionary2: %@", dictionary2);
第十天視頻課程:
了解ARC
自動引用計數(shù)器(Automatic Reference Counting)是Objective-C默認的內存管理機制挚歧,其針對堆上的對象,由編譯器自動生成操作引用計數(shù)的指令(retain或release)吁峻,來管理對象的創(chuàng)建和釋放滑负。
哪些對象受ARC管理:
OC對象指針
Block指針
使用_atteibute_((NSObject))定義的typedef
哪些對象不受ARC管理:
值類型(簡單值類型,C語言struct)如int 锡搜、struct
使用其他方式分配的堆對象(如使用malloc分配)C/C++分配的堆內存也不受ARC管理
非內存資源
引用計數(shù)器管理
新創(chuàng)建(使用alloc, new, copy等)一個引用類型對象橙困,引用計數(shù)為1
BLNPoint *p1 = [[BLNPoint alloc]init];
BLNRectangle *rect = [[BLNRectangle alloc]init];
對象引用計數(shù)器增加1--retain操作:
將對象引用賦值給其他變量或常量:?BLNPoint *p2 = p1;
將對象引用賦值給其他屬性或實例變量:rect.center = p1;
將對象傳遞給函數(shù)參數(shù),或者返回值:draw(p1); //函數(shù)運行結束時ARC就會減1
將對象加入集合中:
array=[[NSMutableArray alloc]initWithCapacity:10];
[array addObject:p1];
對象引用計數(shù)減1--release操作:
將對象局部變量或者全局變量賦值為nil或其他值: p1 = nil;?p2 = nil;
將屬性賦值為nil或其他值:rect.center = nil;
實例屬性所在的對象被釋放:rect = nil;
參數(shù)或局部變量離開函數(shù)
將對象從集合中刪除:[array removeObjectAtIndex:0];
引用計數(shù)變?yōu)?時耕餐,內存自動被釋放凡傅。
引用計數(shù)的內存示意圖,注意如果有兩個對象屬性互相引用肠缔,則要把一邊設置為弱引用夏跷,以防ARC不能正確工作
自動釋放池(Autorelease Pool)
release會導致對象立即釋放。如果頻繁對對象進行release明未, 可能會造成瑣碎的內存管理負擔槽华。autorelease可以將release的調用延遲到自動釋放池被釋放時。
推薦使用自動釋放池(Autorelease Pool)Block趟妥,當其結束時猫态,所有接受autorelease消息的對象將會被立即釋放(即發(fā)送release消息)。
AppKit和UIKit框架在處理每一次事件循環(huán)迭代時披摄,都會將其放入一個Autorelease Pool中亲雪。大多數(shù)情況,無需程序員干預疚膊。
什么時候需要手動管理Autorelease Pool
編寫的程序不基于UI框架义辕,如命名行程序。
在循環(huán)中創(chuàng)建大量臨時對象寓盗,需要更早的釋放灌砖,避免臨時對象聚集導致內存峰值過大璧函。
void poolDemo(){
????? @autoreleasepool {
?????????? ?for (int i = 0; i < 10; i++) {
???????????????? ?__unused? BLNRectangle *rect = [[BLNRectangle alloc]init];
??????????? }
????? }
}
在主線程之外創(chuàng)建新的線程,在新線程開始執(zhí)行處基显,需要創(chuàng)建自己的Autorelease Pool
可以嵌套使用Autorelease Pool
第十一天視頻課程:
認識協(xié)議 Protocol
協(xié)議:類型的合同約定蘸吓,只描述外部接口,不提供具體實現(xiàn)续镇。也稱作類型的行為約定美澳。
協(xié)議可以包含以下成員:屬性、實例方法摸航、類方法制跟、初始化器(不常用)、析構器(不常用)酱虎,協(xié)議中無法包含實例變量成員雨膨。
//聲明一個類并遵守一個協(xié)議
@interface BLNPoint : NSObject //<>里表示這個類遵守Drawable這個協(xié)議,即必須實現(xiàn)Drawable協(xié)議里全部的要求方法(@required)
@property? NSInteger x;
@property? NSInteger y;
@end
//聲明一個類
@protocol Drawable
@property? NSInteger x;
@property? NSInteger y;
-(void)draw;
+(void)createShape;
//-(id)init;
//-(void)dealloc;
@optional //可選擇方法關鍵字(@optional)遵守協(xié)議的類可實現(xiàn)也可以不實現(xiàn)下面的可選擇方法读串,在@optional之上的都是要求方法(@required)
-(void)moveToX:(NSInteger)x withY:(NSInteger)y;
@end
協(xié)議中定義的屬性本質上是訪問器方法聊记,編譯器不會合成實例變量
使用協(xié)議
一個類遵守協(xié)議,需要實現(xiàn)協(xié)議約定的所有@required成員恢暖,協(xié)議中的屬性須在實現(xiàn)類的.h文件中聲明(編譯器合成實例變量需要)協(xié)議不會實現(xiàn)實例變量
注意編譯警告信息:
遵守協(xié)議后卻沒有實現(xiàn)全部必選協(xié)議方法(@required)時排监,會出現(xiàn)警告提示。
協(xié)議類型變量被賦值非協(xié)議類型對象時杰捂,會出現(xiàn)警告提示舆床。
//實現(xiàn)一個參數(shù)遵守協(xié)議的函數(shù)process1
void process1(idobj)
{
????? [obj draw];
????? NSLog(@"[%ld,%ld]",(long)obj.x,(long)obj.y);
}
//調用process1函數(shù)
process1(@“abc”);//此時將出現(xiàn)警告,因為傳遞的@“abc”并沒有遵守協(xié)議
協(xié)議本質上是一種類型嫁佳,可以作為聲明類型挨队,但不能創(chuàng)建實例。
檢查協(xié)議類型
使用conformsToProtocol:檢查對象是否實現(xiàn)了協(xié)議
void process2(id obj){
if ([obj conformsToProtocol:@protocol(AProtocol) ]) {
????? [obj methodA];
}
更多協(xié)議形式
協(xié)議繼承
一個協(xié)議可以繼承一個或多個協(xié)議
實現(xiàn)子協(xié)議的類型蒿往,也必須實現(xiàn)父協(xié)議中約定的成員
協(xié)議組合
可以使用protocol來組合多個協(xié)議
void process4(idobj){
????? [obj methodA];
????? [obj methodC];
}
實現(xiàn)組合協(xié)議的類型盛垦,必須實現(xiàn)組合協(xié)議中的每一個協(xié)議
可選協(xié)議
協(xié)議的某些成員可以定義為optional,不必實現(xiàn)
了解常用協(xié)議
NSObject:包含對象的常用操作瓤漏,相等腾夯、字符串表示、哈希蔬充。
NSCopying:支持復制的類型必須遵守該協(xié)議俯在。
NSMutableCopying:在NSCopying協(xié)議的基礎上,支持復制數(shù)據(jù)的可變性娃惯。
NSFastEnumberation:實現(xiàn)快速枚舉for-in的類型采用。
NSCoding協(xié)議:支持將對象圖像進行編碼/解碼以支持對象序列化肥败。
第十二天視頻課程:
類別 Categroy
類別支持在沒有源代碼的情況下趾浅,基于某些特定的場合愕提,為一個類增加功能。
可以添加:類方法皿哨、實例方法浅侨、重寫基類方法
不能添加:屬性、實例變量证膨、已存在的同名方法如输。本質上類別不可以更改原來的內存模型。
可以使用原有類的實例變量央勒,在類別中添加getter和setter訪問器方法不见。
//NSObject類的聲明
@interface BLNPoint : NSObject
{
????? float _weight;
}
@property NSInteger x;
@property NSInteger y;
-(void)move;
@end
//在類別(Drawing)實現(xiàn)中加入BLNPoint類聲明實例變量_weight的getter和setter訪問器方法,等于把原來類中的實例變量崔步,包裝成了一個屬性稳吮。
-(void)setWeight:(NSInteger)weight
{
????? NSLog(@"Point.setWeight");
????? _weight=weight;
}
-(NSInteger)weight
{
????? NSLog(@"Point.weight");
????? return _weight;
}
命名規(guī)范:類名+擴展方法,如:NSString+Drawing.h/.m
// ?NSString類的類別Drawing的聲明
@interface NSString(Drawing) //()內的Drawing就是類別
-(void)draw;
+(NSString*) convertToString:(NSInteger)number;
@end
類別的使用
使用場景
適合在沒有源代碼的情況下井濒,向已經(jīng)封裝的類中添加方法灶似。
為一個類在某些特殊場景下增加功能。
對于復雜的大型文件分割實現(xiàn)瑞你,同一個類的不同的類別可以放在不同的.m文件中實現(xiàn)酪惭,便于管理,但是不推薦將一個類擴充的特別大者甲。
添加類別
自己創(chuàng)建類
系統(tǒng)的類
第三方庫
擴展 Extension
擴展支持在編譯時春感、有類的源代碼的前提下,向類添加功能过牙∩茫可以將擴展看做匿名的類別。擴展沒有.h文件對內可以訪問寇钉,對外不公開不可以訪問刀疙。(有點像私有成員)
接口定義在.m文件中@implementation前聲明,實現(xiàn)代碼仍然在@implementation內實現(xiàn)扫倡。
擴展支持添加一下成員:
添加屬性
添加實例成員
添加類方法
添加實例方法
改寫屬性的讀寫屬性(可以由readonly改成readwrite谦秧,反之不行)
//擴展的實現(xiàn)
@interface Circle () //擴展在原類名后加()
{
????? NSString * _name;
}
@property (readwrite )NSInteger? radius;//修改讀寫屬性
@property? NSInteger center;//添加屬性
-(float)getDiameter;//實例方法
+(void)process:(Circle*) circle;//類方法
@end
@implementation Circle
+(void)process:(Circle*) circle
{
????? [circle getDiameter];
????? [circle getArea];
}
-(NSInteger)getArea{
????? float area=M_PI*self.radius*self.radius;
????? NSLog(@"Circle Area : %f",area);
????? return area;
}
-(float)getDiameter{
????? float diameter = 2*M_PI*self.radius;
????? NSLog(@"Diameter : %f", diameter );
????? return diameter;
}
@end