属性(Property)
// @property:定义属性关键字
@property (attribute) type name
attribute:
weak:weak弱引用,在setter方法中,对传入的对象不进行引用计数加一的操作,传入的对象没有所有权。
strong:strong强引用,表示实例变量对传入的对象有所有权关系,引用计数加一。
atomic:atomic意为操作是原子性的,只有一个线程访问实例变量。atomic是线程安全的,它是一个默认的特性,但是很少使用,比较影响访问效率。在非ARC编译环境下,需要设置访问锁来保证对该变量的正确getter/setter。
noatomic:noatomic可以被多个线程访问。它的效率比atomic快,但不能保证在多线程环境下的安全性
readonly:readonly表示只有getter没有setter。
readwrite:readwrite是默认值,
assgin:简单赋值,不更改索引计数,适用于简单数据类型。
copy:在内存保留一份传入值的复制,而不是值自身的情况,即把原来的对象完整的复制到另一个新的内存区域,当副本改变是,原对象并不同时改变。
[receiver message] // 消息传递模型
消息message:在iOS开发中,调用一个方法相当于传递一个消息,这里的消息指的是方法名(选择器Selector)和参数。对象不是简单的调用方法,而是相互传递消息。
接收者receiver:通常为一个对象,消息告诉接收者需要去做什么事情。当消息发送的时候,系统从接收者的方法列表中选择最合适的方法并调用。\
发送消息:当需要调用一个方法时,通过给实现该方法的对象发送一条消息来实现,简单来说,就是通知对象去调用其定义的某个方法或者其父类的某个方法。在发送的消息中,包含方法名称以及参数。
选择器selector:因为方法名在消息中负责在对象的方法列表中选择一个方法执行,因此方法名在消息中通常称为选择器。
方法的定义
// 方法声明包含了以下几个部分:方法类型标示符、返回类型、方法名称、参数类型和参数名称,如下所示:
-(void) insertString:(NSString *)astring atIndex:(NSInteget) loc;
1. 方法类型标示符(-) 即这是一个实例方法。 (+) 表示是一个类方法(相当于C++中的 static方法)。
2. 返回类型(void) 即没有返回值。
3. 方法名称(insertString:atIndex:) 一个方法的实际名称是所有签名关键词的串联,包括冒号字符。
4. 参数类型 该方法中包括了两个参数,两个参数的类型为NSString和NSUInteger。
5. 参数名称 该方法中包含了两个参数,两个参数的名称分别为aString和loc。
在Objective-C中,消息是直到运行时才和方法进行绑定关联的。消息机制的关键在于编译器为类和对象生成的结构。
其中类的结构中包含两个基本元素:第一,指向父类的指针;第二,类的方法列表。而对象被创建时,对象的第一个实例变量是一个指向该对象的“类结构”的指针,即isa指针。通过该指针,就可以访问到该类及其父类的方法列表。
对象的创建
NSString *str = [[NSString alloc] init];
alloc:分配内存空间,将对象的引用计数(ReferenceCount)设置为1。初始化对象的isa指针并指向对象的类。将类中定义的属性(实例变量)的值初始化为0或者nil。
init:对象初始化,初始化的过程将对象的实例变量设置为合理且有用的初始值,还可以分配和准备对象需要的其他全局资源,并在必要时加载诸如文件这样的资源。
判断对象的类型
对象通过调用isKindOfClass:方法,可以判断对象的类型。isKindOfClass:方法是NSObject类的方法,将类型为Class的对象aClass作为参数传入,返回一个BOOL类型的返回值。isKindOfClass:方法还可以用于判断子类对象的类型。
-(BOOL) isKindOfClass:(Class)aClass;
NSString *str = [NSString stringWithFormat:@"Hello World"];
if ([str isKindOfClass:[NSString Class]]) {
NSLog(@"NSStirng");
}
判断对象是否响应消息
要判断一个对象是否响应一条消息,则可以调用respondsToSelector:方法。应用程序通常在验证一个对象响应一则消息后,才将消息发送给该对象。这种机制常常用于代理中,先判断代理对象是否响应代理方法,如果响应,则代表代理对象中已经实现了代理方法,然后再通知代理对象执行代理方法。
NSString *str = [[NSString alloc] init];
if ([str respondsToSelector:@selector(length)]) {
NSLog(@"str可以响应名称为length的消息")
}
对象间的比较
当需要对比两个对象是否相同时,可以使用isEqual:方法。如果相同,则该方法返回YES。
-(BOOL)isEqual:(id)object;
NSString *str1 = [NSString stringWithFormat:@"www.csdn.com"];
NSString *str2 = @"www.baidu.com";
if ([str1 isEqual:str2]) {
NSLog(@"object equal");
}
if ([str1 isEqualToString:str2]) {
NSLog(@" str1 equal str2");
}
对象复制
通过调用copy方法,可以创建对象的副本。调用copy方法,有个前提条件,即接收的对象的类必须遵守NSCopying协议。另外,在使用对象复制时,还需要考虑针对该对象是深复制(对象复制),还是浅复制(指针复制)
// 遵守 NSCopying 协议
@interface NSString : NSObject<NSCopying, NSMutableCopying, NSSecureCoding>
NSString *str = [NSString stringWithFormat:@"www.csdn.com"];
// 对象复制
NSString *copyString = [str copy];