Objctive-C - 基础知识点整理(持续更新)

2019-10-23  本文已影响0人  75b9020bd6db
1.请说明并比较以下关键词:strong, weak, assign, copy, unsafe_unretained
// 测试 weak 和 strong
@property (nonatomic, strong) Person *strongPerson;
@property (nonatomic, weak) Person *weakPerson;

// 测试代码
self.strongPerson = [Person new];
self.weakPerson = self.strongPerson;
self.strongPerson = nil; 
NSLog(@"strongStr = %@, weakStr = %@", self.strongPerson, self.weakPerson);

// 打印结果:说明weak修饰的属性并不会使引用计数增加
strongStr = (null), weakStr = (null)

稍微改一下代码:

self.strongPerson = [Person new];
self.weakPerson = self.strongPerson;
self.weakPerson = nil;
NSLog(@"strongStr = %@, weakStr = %@",self.strongPerson, self.weakPerson);

// 打印结果:说明weak修饰的属性只是对对象的弱引用,并不会真正的持有该对象。
strongStr = <Person: 0x600000007c40>, weakStr = (null)

再次修改代码验证:

Person *p = [Person new];
self.strongPerson = p;
self.weakPerson = self.strongPerson;
p = nil;
NSLog(@"strongStr = %@, weakStr = %@",self.strongPerson, self.weakPerson);

//打印结果:说明strong属性会强引用该对象并使该对象的引用计数+1,
//所以即使把p设置为nil,该对象也并没有释放,要想释放该对象,
//还得把strongStr设置为nil
strongStr = <Person: 0x600000200b40>, weakStr = <Person: 0x600000200b40>

self.strongPerson = nil;
// 打印结果:
strongStr = (null), weakStr = (null)
再来看看copy关键字
// 在ViewController里面加个属性:
@property (nonatomic, copy) NSObject *c;

// 在.m中
NSObject *a = [[NSObject alloc]init];
self.c = a;
a = nil;
NSLog(@"%@",self.c);

毫无疑问,输出结果不为nil:
<NSObject: 0x600000010e80>

  • 注意:在使用 NSMutableArray, NSMutableDictionary等可变集合对象的时候,千万不要用copy进行修饰,这里用copy很可能会出错,因为当你给该属性赋值时,它会自动调用对象的copy方法,从而将可变集合转换成不可变集合,把一个不可变集合赋值给一个可变集合,再调用addObject等方法就会报错,因为变成了不可变对象。
2.请说明并比较以下关键词:__weak__block

*__weakweak基本相同。前者用于修饰变量(variable),后者用于修饰属性(property)。__weak 主要用于防止block中的循环引用。

3. 请说明并比较以下关键词:atomatic, nonatomic
4. 请说明并比较synthesize和@dynamic,分别有什么作用?

我们平时完成属性定义后,编译器自动编写访问这些属性所需的方法,用以访问给定类型中具有给定名称的变量,这个过程叫做“自动合成”( autosynthesis),简单讲就是:@property = getter + setter

@interface Person : NSObject
@property NSString *firstName;
@property NSString *lastName;
@end

上述代码与下面等效:

@interface Person : NSObject
- (NSString *)firstName;
- (void)setFirstName:(NSString *)firstName;
- (NSString *)lastName;
- (void)setLastName:(NSString *)lastName;
@end

上面的过程由编译器在编译期间帮我们完成,所以编辑器里看不到这些“合成方法”(synthesized method)的源代码。除了生成方法代码 gettersetter之外,编译器还要自动向类中添加对应类型的实例变量,并且在属性名前面加下划线,以此作为实例变量的名字。在前例中,会生成两个实例变量,其名称分别为 _firstName_lastName。当然我们也可以在类的实现代码里通过@synthesize语法来指定实例变量的名字。

@implementation Person
@synthesize firstName = _myFirstName;
@synthesize lastName = myLastName;
@end

@property有两个对应的词,一个是@synthesize,一个是@dynamic。如果两个都没写,那么默认就是@syntheszie var = _var;

5. 什么是ARC
上一篇下一篇

猜你喜欢

热点阅读