為了描述方便,把如下代碼貼出來:
@interface Student:NSObject
-(void)go;
-(void)showName:(NSString *)name;
-(void)introduce:(NSString *)name :(NSString*)address;
@end
Student* stu = [[Student alloc]init];
一 創建和初始化方法
alloc
allocWithZone
new
copy -- 只有不可變到不可變是淺拷貝(相當於retain),其他都是深拷貝,產生不可變的副本(NSString, NSSet等)
mutableCopy -- 深拷貝,產生可變的副本(NSMutablString, NSMutablSet等)
init
重點看copy和mutableCopy
copy:只有不可變到不可變是淺拷貝(相當於retain),其他都是深拷貝,產生不可變的副本(NSString, NSSet等)
mutableCopy:深拷貝,產生可變的副本(NSMutablString, NSMutablSet等)
並不是所有的對象都支持copy,mutableCopy;
遵守NSCopying/NSMutableCopying協議的類可以發送copy/mutableCopy消息。
這兩個協議裡面分別聲明了下面兩個方法:
- (id)copyWithZone:(NSZone *)zone;
- (id)mutableCopyWithZone:(NSZone *)zone;
示例:
@interface Student:NSObject
@end
@interface Student
(id)copyWithZone:(NSZone *)zone
{
// 創建的副本對象不需要釋放,有調用者釋放
// [self class]防止繼承之後,返回父類對象
Student* copy = [[[self class] allocWithZone:zone] init];
return copy;
}
@end
二 內存管理方法retain 增加對象的計數器retainCount 返回一個對象當前的計數器release 減少對象的計數器autorelease 自動減少對象的計數器,但是以推遲的方式來實現。dealloc 應用於類來釋放對象實例變量並釋放動態內存三 判斷方法isKindOfClass:判斷對象是否是某個類或子類的對象isMemberOfClass:判斷對象是否是某個類的對象comfirmsToProtocal:判斷對象是否實現了某個協議instancesRespondToSelector:判斷對象是否實現了某個方法respondsToSelector:判斷類是否實現了某個方法四
間接調用performSelector:performSelector:withObjct:performSelector:withObjct:withObjct:performSelector:withObjct:afterDelay:// 相當於[stu go];
[stu performSelector:@selector(go)];
// 相當於[stu showName:@"Jun"];
[stu performSelector:@selector(showName:) withObjct:@"Jun"];
相當於[stu introduce:@"Jun":@"address"];
[stu performSelector:@selector(introduce::) withObjct:@"Jun" withObjct:@"address"];
// 延時2秒之後調用
[stu performSelector:@selector(showName:) withObjct:@"Jun" afterDelay:2];
五 描述
NSObject有一個description方法
+ (NSString *)description;
當我們調用NSLog(@"%@", instance);時,就會調用description方法。
自定義類時,可以重寫這個方法。
六 反射
根據字符串反射成類和方法
1 Class反射
// 字符串類名到類
NSString* className = @"Student";
Class class = NSClassFromString(className);
Person* p = [[class alloc] init];
// 類到字符串類名
NSString* strClass = NSStringFromClass([Person class]);
2 方法反射
// 字符串方法名到方法
NSString* funName = @"go";
SEL selector = NSSelectorFromString(funName);
[stu performSelector:selector];
// 方法到字符串方法名
NSString* strFun = NSStringFromSelector(selector);
七 NSObject本質
@interface NSObject {
Class isa;
}
可以看到NSObject對象只有一個成員變量Class isa;
Class又是什麼呢?
typedef struct objc_class *Class;
它結構體objc_class指針的別名。
objc_class的定義如下:
struct objc_class {
Class isa;
};
跟NSObject定義類似,此外還有id也是這樣的。
typedef struct objc_object {
Class isa;
} *id;
所以id就是結構體objc_object指針。
從上面可以看出,NSObject,objc_class,objc_object都僅有一個objc_class * 類型,也就是Class類型的變量isa
以得出結論,類是用objc_class結構體表示的,對象是用objc_object結構體表示的,對象的isa用來標示這個對象是哪個類的實例。
看下面的源代碼:
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
- (Class)class {
return object_getClass(self);
}
Class object_getClass(id obj)
{
return _object_getClass(obj);
}
static inline Class _object_getClass(id obj)
{
if (obj) return obj->isa;
else return Nil;
}
如果obj不空,返回的Class類型就是obj->isa,否則,返回的是Nil。
這就從源碼上證實了isa就是代表一個對象的類型。