objective-c 简要学习笔记

来源:互联网 发布:unity后期美工师招聘 编辑:程序博客网 时间:2024/05/16 17:40
类基础
@interface 类的声明
{//成员数属性,必须是大括号包围起来,默认是是@protected
@private
NSString *_name;
int _age;
@protected
NSString *_nation;
@public
float height;
}

@property(readwrite/readonly,atomicity/nonatomic,assign/retain/copy) type name
//推荐做法是NSString用copy,delegate用assign(暂时不理解),非objc数据类型,比如int,float等基本数据类型用assign(默认就是assign),而其它objc类型,比如NSArray,NSDate用retain
copy:拷贝,复制一个对象并创建strong关联,引用计数为1 ,原来对象计数不变。
assign(默认):赋值,不涉及引用计数的变化,弱引用。ARC中对象不能使用assign,但原始类型(BOOL、int、float)仍然可以使用。
retain:持有,对原对象引用计数加1,强引用。ARC中使用strong。
weak:赋值(ARC),比assign多了一个功能,对象释放后把指针置为nil,避免了野指针。
strong(ARC默认属性):持有(ARC),等同于retain。


@end
关于属性变量与成员变量间的关系:
1:如果只声明一个属性a,不使用@synthesize实现:编译器会使用_a作为属性的成员变量
2:如果声明了一个属性a,使用自定义的Setter或者Getter,编译器使用属性a作为属性的成员变量。
3:如果声明了一个属性a,使用@synthesize a进行实现,但是实现过程中没有指定使用的成员变量:则此时编译器会使用a作为属性的成员变量
4:如果声明了一个属性a,使用@synthesize a=_a进行实现,这个过程已经指定了使用的成员变量:此时会使用指定的成员变量作为属性变量

@implementtation 类的定义
ObjC实例化需要两个步骤:分配内存,初始化 [[ClassName alloc] init] == [ClassName new]

内存管理: @autoreleaespool 与类在初始化时调用autorelease协同作用,在pool程序运行过pool的代码后会自动让发送过autorelease信息的实例,release一次。


objective-c KVO(的键(key)-值(value)观察)
KVO:相当于设计模式的观察者模式
运用接口函数:
两种方式:自动模式与手动模式
默认自动模式:
1:注册与解除注册
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;
参数说明:由被观察者(设计模式中的Subject)调用addObserver, 第一个参数是观察者实例(设计模式中的observer) 相当于设计模式中的attach
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath; 相当与设计模式中的deattach
2:观察者实现的接口方法:观察多个key时,可以在该函数中判断需要的keyPath,进行特殊处理。
observeValueForKeyPath:(NSString *)keyPath #观察的key
ofObject:(id)object #被观察者的对象
change:(NSDictionary *)change # [[change objectForKey:@"old"] floatValue]
context:(void *)context #自定义内容
值类型:
  NSKeyValueObservingOptionNew 把更改之前的值提供给处理方法
  NSKeyValueObservingOptionOld 把更改之后的值提供给处理方法
行为行:
  NSKeyValueObservingOptionInitial 把初始化的值提供给处理方法,一旦注册,立马就会调用一次。通常它会带有新值,而不会带有旧值。
  NSKeyValueObservingOptionPrior 分2次调用。在值改变之前和值改变之后。
可以用或观察多个类型


手动模式:
1:触发事件接口函数
被观察者:
[self willChangeValueForKey:@"age"];
修改key age = theAge;
[self didChangeValueForKey:@"age"];
+ (BOOL) automaticallyNotifiesObserversForKey:(NSString *)key {
if ([key isEqualToString:@"age"]) {
return NO;
}
return [super automaticallyNotifiesObserversForKey:key];
}
首先,需要手动实现属性的 setter 方法,并在设置操作的前后分别调用 willChangeValueForKey: 和 didChangeValueForKey方法,这两个方法用于通知系统该 key 的属性值即将和已经变更了;
其次,要实现类方法 automaticallyNotifiesObserversForKey,并在其中设置对该 key 不自动发送通知(返回 NO 即可)。这里要注意,对其它非手动实现的 key,要转交给 super 来处理。

依赖键:有时候一个属性的值依赖于另一对象中的一个或多个属性,如果这些属性中任一属性的值发生变更,被依赖的属性值也应当为其变更进行标记。
步骤:
1:观察依赖键:observeValueForKeyPath:ofObject:change:context: 中添加处理变更通知的代码
if ([keyPath isEqualToString:@"key"])
2:实现依赖键:keyPathsForValuesAffectingInformation 或 keyPathsForValuesAffectingValueForKey: 方法来告诉系统 information 属性依赖于哪些其他属性,这两个方法都返回一个key-path 的集合。在这里要多说几句,如果选择实现 keyPathsForValuesAffectingValueForKey,要先获取 super 返回的结果 set,然后判断 key 是不是目标 key,如果是就将依赖属性的 key-path 结合追加到 super 返回的结果 set 中,否则直接返回 super的结果。

参考详细链接:http://www.cppblog.com/kesalin/archive/2012/11/17/kvo.html


对象复制
objective-c 对象复制必须实现<NSCopying> <NSMutableCopying>协议,
copy copyWithzZone 拷贝的对象是一个可变时,副本可变
mutableCopy mutableCopyWithZone 无论源对象是否可变,副本是是可变的。
浅拷贝的实现:

-(id)copyWithZone:(NSZone *)zone{

Person *person = [[[self Class]allocWithZone:zone]init];

p.name = _name;

p.age = _age;

return person;

}

深拷贝的实现

-(void)copyWithZone:(NSZone *)zone{

Person *person = [[[self Class]allocWithZone:zone]init];

person.name = [_name copy];

person.age = [_age copy];

return person;

}


0 0