面試題
1)@property 能使用哪些關鍵字杰捂、作用是什么翰灾;下面這4種寫法的區(qū)別赞弥?
@property (nonatomic, strong) NSArray *array0;//mutableArray copy 成array0時正罢,如果array0種的值被改了阵漏,會出什么問題呢
@property (nonatomic, copy) NSArray *array1;//常規(guī)寫法
@property (nonatomic, strong) NSMutableArray *array2;//標準寫法
@property (nonatomic, copy) NSMutableArray *array3;// 把Array mutablecopy 成 array3后,array3其實還是 Array對象翻具,如果向其中插入對象的話履怯,則會造成crash
copy的深淺拷貝只說是不正確的。
copy 是相對于mutablecopy來說裆泳,Array mutablecopy可以變成MutableArry叹洲, MutableArry可以copy成Array。同理還有NSdiction工禾。
一個Array mutablecopy 成一個 MutableArray后运提,Array里面的東西還是原來的東西,里面的元素并沒有重新new一個新的東西申請新的內存闻葵,這個是淺拷貝民泵,并不是之前說的深拷貝。
2) 下邊對象分別都在什么時候釋放
- (void)ARCProblem{
id obj0 = @"sunnyxx"; //會一直在
__weak id obj1 = obj0; //__weak obj1的地址指向obj0的對象槽畔,所以只要obj0不釋放obj1就不會被釋放
__strong id obj2 = [NSObject new];//obj2 會在用完的時候栈妆,obj2被釋放
__weak id obj3 = [NSObject new]; //obj3 在賦值之后就會被釋放,因為沒有人強引用obj3,所以在這行結束 obj3就會被釋放
{
id obj4 = [NSObject new];// 在{}區(qū)域結束的時候會被釋放
}
__autoreleasing id obj5 = [NSObject new];// obj5是個自動釋放的對象鳞尔,obj5會被加到自動釋放池中嬉橙,會在一個最近的自動釋放池中被釋放,如果是ARC外面有個autoreleasPool 則會在那個時候被釋放寥假,如果是在viewdidload中市框,則會在runloop的autoreleasPool中釋放。
__unsafe_unretained id obj6 = self;//相當于retain糕韧,obj6不會對self進行影響枫振,理論上obj6在任何時候都會被釋放。 unsafe不保證對象時刻都有兔沃,可能隨時銷毀蒋得。
}
3) 會發(fā)生什么
- (void)viewDidLoad {
[super viewDidLoad];
self.view = nil;
//view Did Load 是在view被load的時候被調用,self.view 是個懶加載的屬性乒疏,第一次在.view的時候额衙,會load一下view相關方法,在加載完成后悔通知VC執(zhí)行viewDidLoad方法
// 所以在self.view = nil 的時候
// 很有可能出現遞歸怕吴,但是如果沒有再次調用 self.view 也可能不會出現遞歸窍侧,出現黑屏現象
}
4) block 循環(huán)引用的三種解決方案
//如何解決下面代碼的問題
- (void)blockRetainCycleProblem{
self.block = ^{
NSLog(@"%@",@[self]);
};
}
// ===== 三種解決辦法
- (void)blockRetainCycleProbleAnswer0{
__weak typeof(self) weakSelf;
self.block = ^{
NSLog(@"%@",@[weakSelf]);
};
}
- (void)blockRetainCycleProbleAnswer1{
__weak typeof(self) weakSelf;
self.block = ^{
__weak typeof(weakSelf) strongSelf = weakSelf;
NSLog(@"%@", @[strongSelf]);
// 確保在 block塊內 self不會被釋放, 如果放倒數組里帶出block區(qū)域,則可能造成crash转绷,self可能被釋放掉
};
}
- (void)blockRetainCycleProbleAnswer2{
__weak typeof(self) weakSelf;
self.block = ^{
__weak typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
NSLog(@"%@",@[strongSelf]);
}
};
}
5)Block內存管理Extension
///下面的 self 用不用weak
- (void)blockRetainCycleProblemExt{
// 下面的 self 用不用weak
[UIView animateWithDuration:1 animations:^{
self.view.frame = CGRectMake(1, 2, 3, 4);
// 這行block 是瞬間執(zhí)行的伟件,在這行代碼走完,會立即調用這個block方法
}];
//那這個呢
[UIView animateWithDuration:1 delay:1000 options:0 animations:^{
self.view.frame = CGRectMake(4, 1, 2, 3);
// 這個也是瞬間執(zhí)行
} completion:nil];
}
6)代碼規(guī)范
#pragma mark - 代碼規(guī)范 (問題)
typedef enum {
UserSex_Man,
UserSex_Womain
}UserSex;
@interface UserModel : NSObject
@property(nonatomic, strong) NSString *name;
@property(assign, nonatomic) int age;
@property (nonatomic, assign) UserSex sex;
-(id)initUserModelWithUserName: (NSString*)name withAge:(int)age;
-(void)doLogIn;
@end
#pragma mark - 正確的代碼規(guī)范
typedef NS_ENUM(NSUInteger, XXUserGender) {
XXUserGenderUndefined,
XXUserGenderMale,
XXUserGenderFemale
};
@interface XXUserModel : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) XXUserGender gender;
-(instancetype)initWithUsername:(NSString *)name age:(NSInteger)age;
-(void)login;
@end