iOS 需要注意的细节
2017-08-14 本文已影响29人
Never_Yg
C语言最重要的:指针, 链表, 结构体
结构体分配在栈区
对象分配在堆区
1,@class
如果只需要使用类名,不需要知道其中细节,可以使用@class, 这样可以减少编译事件(可以避免无用导入问题)
好处:
- 减少引入头文件的数量, 减少编译时间
- 解决循环引用问题
A, B两个类, A类中有B类的属性对象, B类中有A类的属性对象 那么,在解析A类的头文件时, 编译器会发现B类的头文件, 而B类的头文件中又引入了A类的头文件,就这样反反复复最终会导致一个类无法正确被编译 解决办法: 只需两个类中的任意一个导入#import换成@class
2,多用字面量(就为简单易懂)
NSArray *languages = @[@"PHP", @"Objective-C", someObject, @"Swift", @"Python"];
NSString *Swift = languages[2];
NSDictionary *dict = @{@"key" : @"value"};
NSString *value = languages[@"key"];
3, static const enum #define什么时候用?
- static 声明静态变量
- const 声明不可变变量 在指针前表示值可以修改指针地址不会变, 在后, 表示值不可以改变
- define 编译时全局替换, 增加编译时间
- extern 修饰全局变量
//.h文件中
extern NSString *const kName;
//.m文件中
NSString *const kName = @"Alun Chen";
- 定义不对外公开的常量时
static NSString * const kConst = @"Hello";
static const CGFloat kWidth = 10.0;
- 多用枚举表示状态
4 理解属性
-
不希望的属性改变---readonly
-
atomic并不能保证线程安全,只在当前线程安全, 因为给属性的getter and setter加锁了
@synchronized(self) { //关键代码; }
-
可变属性用copy, 不可变属性用strong
//错误的属性声明 @property (nonatomic, copy) NSArray *arrayOfCopy; @property (nonatomic, strong) NSMutableArray *mutableArrayOfStrong;
-
self和_下划线
self.是通过getter和setter方法,访问属性
_下划线 是获取自己的实例变量默认情况下编译器会帮我们生成getter setter方法, 若当前类中有, 则编译器跳过,不会再生成, 使用用户自定义的方法 也就是说, 使用self.时是调用一个getter方法. 会使引用计数加1, 而_下划线不会使用引用计数加1 故: 使用self.是更好的选择, 1. 可以兼容懒加载 2. 同时避免了使用下划线忽略self这个指针, 后者容易在block中造成循环引用
5 == 在OC是比较指针地址是否相同
6 尽量使用不可变对象, 保证数据安全
如果要修改, 应提供方法
//Language.h
@property (nonatomic, strong, readonly) NSSet *languages;
- (void)addLanguage:(NSString *)language;
- (void)removeLanguage:(NSString *)language;
//**.m
@implementation Language {
NSMutableSet *mutableLanguages;
}
- (NSSet *)languages {
return [_mutableLanguages copy];
}
- (void)addLanguage:(NSString *)language {
{
[_mutableLanguages addObject:language];
}
- (void)removeLanguage:(NSString *)language
{
[_mutableLanguages removeObject:language];
}
7 消息发送机制
消息传递的关键是, 编译器构建每个类和对象是都包含两个必要元素
- 指向父类的指针 isa
- 调度表(dispatch table) 调度表是将类的selector与方法的实际内存地址关联起来
当向一个对象发送消息时,objc_msgSend方法根据对象的isa指针找到对象的类,然后在类的调度表(dispatch table)中查找selector。如果无法找到selector,objc_msgSend通过指向父类的指针找到父类,并在父类的调度表(dispatch table)中查找selector,以此类推直到NSObject类。一旦查找到selector,objc_msgSend方法根据调度表的内存地址调用该实现。