iOS开发Tip之二
如何给NSArray添加弱引用对象
使用NSValue做一个包装,再添加到NSArray
1
NSValue * weakValue = [NSValue valueWithNonretainedObject:[NSObject new]];
将main.m 展开为C代码
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
在子线程里面开启runloop的话,必须要添加autoreleasepool,不然会引发内存泄漏
每个子线程在开始的地方会有一个autoreleasepool,结束的时候清空pool,但是因为runloop导致线程无法结束,所以如果不手动添加pool,那么必然会内存泄漏
给一个可变对象的@property使用copy修饰,必须override这个属性,并用mutableCopy代替copy
如何调试EXC_BAD_ACCESS错误
一般情况下是因为访问了已经被释放的对象造成的。这种对象称之为僵尸对象(Zombie Objects)。
我们可以打开Scheme->Diagnostics中的Enable Zombie Objects选项。这样程序运行过程中所有引用计数为0的对象都不会被销毁,当对僵尸对象发送消息的时候就会触发错误,并在控制台中打印出相应的错误。
以下是模拟僵尸对象的代码
1
2
3
4
5NSString * str = [NSString stringWithCString:"hello world" encoding:NSUTF8StringEncoding];
__unsafe_unretained NSString * zombie = str;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[zombie uppercaseString];
});打开Enable Zombie Objects选项之后终端输出为:
1
2objc[57939]: Class _NSZombie_OS_xpc_endpoint is implemented in both ?? (0x60c0000495d0) and ?? (0x60c0000497e0). One of the two will be used. Which one is undefined.
2018-08-08 23:08:21.682727+0800 demo1[57939:39012491] *** -[CFString uppercaseString]: message sent to deallocated instance 0x60c00003b3a0用@property写一个单例,逼格更高
1
@property (nonatomic, class, readonly, nonnull) SDImageCachesManager *sharedManager;
实现和平常一样
1
2
3
4
5
6
7
8+ (SDImageCachesManager *)sharedManager {
static dispatch_once_t onceToken;
static SDImageCachesManager *manager;
dispatch_once(&onceToken, ^{
manager = [[SDImageCachesManager alloc] init];
});
return manager;
}用法
1
[SDImageCachesManager.sharedManager addCache:newCache];
绝对禁止给Category覆盖父类方法
因为Category中的方法无法调用父类方法,所以会造成不可预料的覆盖。理论上Category只能新增方法。