id __weak obj = nil;
{
id __strong obj1 = [[NSObject alloc] init];
obj = obj1;
}
NSLog(@"%@",obj);
- 輸出
nil
刁品, __weak
修飾符的變量不持有對(duì)象身腻,在超出變量作用域時(shí)检疫,對(duì)象就會(huì)被釋放并會(huì)被置為 nil
施禾。
//不使用第三個(gè)變量,交換兩個(gè)變量的值
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
函數(shù)
-
super
本質(zhì)是調(diào)用 objc_msgSendSuper2
函數(shù)
- (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;
本質(zhì)是向 runloop
中添加定時(shí)器
- 子線程默認(rèn)未開啟
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
表示是否等待當(dāng)前 selector
任務(wù)完成后再執(zhí)行后續(xù)任務(wù)
- (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];
執(zhí)行 NSLog(@"1");
后 thread
就銷毀了
-
waitUntilDone
為 YES
時(shí)候需注意所在線程生命周期是否正常
for (NSInteger i = 0; i < 100; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
self.name = [NSString stringWithFormat:@"%@", @"qwertyuiopasdfghjkl"];
});
}
//多個(gè)線程同時(shí)調(diào)用[_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"];
});
}
-
Tagged Pointer
數(shù)據(jù)存儲(chǔ)在指針中
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
不捕獲镀层,直接使用