id __weak obj = nil;
{
id __strong obj1 = [[NSObject alloc] init];
obj = obj1;
}
NSLog(@"%@",obj);
- 输出
nil
, __weak
修饰符的变量不持有对象,在超出变量作用域时,对象就会被释放并会被置为 nil
。
//不使用第三个变量,交换两个变量的值
int a = 6;
int b = 8;
a = a + b;
b = a - b;
a = a - b;
#import <Foundation/Foundation.h>
@interface Person : NSObject
@end
@interface Student : Person
@end
#import "Person.h"
@implementation Person
@end
@implementation Student
- (instancetype)init {
self = [super init];
if (self) {
NSLog(@"self.class = %@", self.class);
NSLog(@"super.class = %@", super.class);
NSLog(@"self.superclass = %@", self.superclass);
NSLog(@"super.superclass = %@", super.superclass);
}
return self;
}
@end
self.class = Student
super.class = Student
self.superclass = Person
super.superclass = Person
-
objc_msgSend
函数
-
super
本质是调用 objc_msgSendSuper2
函数
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"1");
[self performSelector:@selector(text) withObject:nil afterDelay:0];
NSLog(@"3");
});
}
- (void)test {
NSLog(@"2");
}
1
3
-
- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay;
本质是向 runloop
中添加定时器
- 子线程默认未开启
runloop
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"1");
[self performSelectorOnMainThread:@selector(test) withObject:nil waitUntilDone:YES];
NSLog(@"3");
}
- (void)test {
NSLog(@"2");
}
//waitUntilDone:YES
1
2
3
//waitUntilDone:NO
1
3
2
-
waitUntilDone
表示是否等待当前 selector
任务完成后再执行后续任务
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSThread *thread = [[NSThread alloc] initWithBlock:^{
NSLog(@"1");
}];
[thread start];
[self performSelector:@selector(text) onThread:thread withObject:nil waitUntilDone:YES];
}
- (void)test {
NSLog(@"2");
}
1
*** Terminating app due to uncaught exception 'NSDestinationInvalidException', reason: '*** -[ViewController performSelector:onThread:withObject:waitUntilDone:modes:]: target thread exited while waiting for the perform'
-
[thread start];
执行 NSLog(@"1");
后 thread
就销毁了
-
waitUntilDone
为 YES
时候需注意所在线程生命周期是否正常
for (NSInteger i = 0; i < 100; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
self.name = [NSString stringWithFormat:@"%@", @"qwertyuiopasdfghjkl"];
});
}
//多个线程同时调用[_name release];
//解决办法加锁。
EXC_BAD_ACCESS
- (void)setName:(NSString *)name {
if (_name != name) {
[_name release];
_name = [name copy];
}
}
for (NSInteger i = 0; i < 100; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
self.name = [NSString stringWithFormat:@"%@", @"qwe"];
});
}
NSInteger a = 10;
static NSInteger b = 100;
void (^block)(void) = ^ {
NSLog(@"a = %ld", a);
NSLog(@"b = %ld", b);
};
a = 20;
b = 200;
block();
a = 10
b = 200
- 局部
auto
变量,block
值捕获
- 局部
static
变量,block
指针捕获
- 全局变量,
block
不捕获,直接使用