一、以下代码能不能执行成功?如果可以,打印结果是什么?
// Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
- (void)test;
@end
// Person.m
#import "Person.h"
@implementation Person
- (void)test
{
NSLog(@"test print name is : %@", self.name);
}
@end
// ViewController.m
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
id cls = [Person class];
void *obj = &cls;
[(__bridge id)obj test];
}
答:可以打印成功,打印结果test print name is : <ViewController: 0x7f95514077a0>
原理解析:
1、id cls = [Person class]; void *obj = &cls; [(__bridge id)obj test];
结构解析
2、 [super viewDidLoad];
内部objc_super2
结构体内存储如下
struct objc_super = {
self,
[ViewController Class]
};
3、局部变量在栈空间内是由高地址向低地址连续存储的
屏幕快照 2018-07-16 下午12.07.15.png
二、下面代码的打印结果是什么?
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
NSLog(@"1");
[self performSelector:@selector(test) withObject:nil afterDelay:.0];
NSLog(@"3");
});
- (void)test
{
NSLog(@"2");
}
打印结果是 1、3
原因:
-
performSelector:withObject:afterDelay:
的本质是往Runloop中添加定时器 - 子线程默认没有启动Runloop
- 如果想要正常调用test,代码如下
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
NSLog(@"1");
[self performSelector:@selector(test) withObject:nil afterDelay:.0];
NSLog(@"3");
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
});
三、指出以下两种property的写法,分别可能造成什么隐患?
@property (nonatomic,strong)NSArray *arr;
@property (nonatomic,copy) NSMutableArray *mutableArr;
- 1、当把arr赋值给可变数组,在可变数组改变的时候,arr会跟着变化。
- 2、mutableArr用copy修饰,会生成不可变数组,当给数组添加元素的时候,会报如下错误
-[__NSArray0 addObject:]: unrecognized selector sent to instance
。
网友评论