1、Category如何添加属性
给分类中添加属性,主要目的是为了解耦。如果是按照通常的方法去给添加属性,只会对getter和setter方法进行声明,而category又是在运行时决定的,因此需要使用runtime的两个方法(objc_setAssociatedObject,objc_getAssociatedObject)来重写getter和setter方法,代码如下:
#import <Foundation/Foundation.h>
@interface NSString (MyCategory)
@property (nonatomic, assign) NSInteger index;
@end
#import "NSString+MyCategory.h"
#import <objc/runtime.h>
static const void *IndexKey = &IndexKey;
@implementation NSString (MyCategory)
- (void)setIndex:(NSInteger)index {
objc_setAssociatedObject(self, IndexKey, @(index), OBJC_ASSOCIATION_ASSIGN);
}
- (NSInteger)index {
return [objc_getAssociatedObject(self, IndexKey) integerValue];
}
@end
2、weak、strong、copy、assign属性
weak:
可以用来修饰对象和基本数据类型,weak是一种非持有特性,使用weak修饰的对象将不会被持有,是一种弱引用,在对象被释放以后,其指向的指针会被置为nil。在Objective-C中,向nil发送消息是安全的,不会造成野指针的问题导致崩溃。通常delegate和block的使用都是用weak进行修饰的。
weak其实就是hash表,表里key值就是对象的指针,value就是weak的指针地址。
strong和copy:
今天利用数组对strong和copy做了一个简单的测试,直接上代码
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) NSArray *arrStrong;
@property (nonatomic, copy) NSArray *arrCopy;
@property (nonatomic, strong) NSArray *arrStrong1;
@property (nonatomic, copy) NSArray *arrCopy1;
@property (nonatomic, strong) NSMutableArray *mutableArr;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.mutableArr = [NSMutableArray array];
[self.mutableArr addObject:@"1"];
self.arrCopy = self.mutableArr;
self.arrStrong = self.mutableArr;
self.arrCopy1 = [NSArray arrayWithArray:self.mutableArr];
self.arrStrong1 = [NSArray arrayWithArray:self.mutableArr];
NSLog(@"copy1 = %@", self.arrCopy);
NSLog(@"strong1 = %@", self.arrStrong);
NSLog(@"copy2 = %@", self.arrCopy1);
NSLog(@"strong2 = %@", self.arrStrong1);
[self.mutableArr addObject:@"2"];
NSLog(@"copy3 = %@", self.arrCopy);
NSLog(@"strong3 = %@", self.arrStrong);
NSLog(@"copy4 = %@", self.arrCopy1);
NSLog(@"strong4 = %@", self.arrStrong1);
}
可以从打印中看出来,使用=直接进行赋值操作时,copy修饰的对象是属于值赋值,strong修饰的对象是指针赋值,所以当可变数组的值发生改变时,strong数组的值也会发送改变(其实最好用字符串进行验证);在使用arrayWithArray进行赋值操作时,都会将数组重新指向一个新的地址,属于值赋值。
深拷贝和浅拷贝
对于不可变对象来说,copy是浅拷贝,只会拷贝对象的内存地址,就是把当前对象的指针指向了原来对象的地址;而mutableCopy会重新分配一块内存空间,将新对象的指针指向新分配的内存地址。
对于可变对象来说,不管是copy和mutableCopy都是深拷贝,都会将对象的指针指向重新分配的内存地址。
关键词开头命名的属性防止编译器报错
@property (nonatomic, strong, getter=l_copyStr, setter=setL_copyStr:) NSString *copyStr;
@synthesize和@dynamic
@synthesize:如果我们没有手动实现getter和setter两个方法,编译器会自动帮我们实现
@dynamic:告诉编译器属性的getter和setter方法由我们手动来实现,如果没实现的话,编译的时候可以通过,但是运行时会崩溃。