Skip to content

Commit 4adb348

Browse files
authored
Merge pull request bestswifter#4 from upworldcjw/master
监听对象释放。优化log输出
2 parents 03128c8 + 70dc62d commit 4adb348

4 files changed

Lines changed: 86 additions & 4 deletions

File tree

RunloopAndThread/RunloopAndThread.xcodeproj/project.pbxproj

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
9BAA82B11D451A0E00E5B98A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9BAA82AF1D451A0E00E5B98A /* Main.storyboard */; };
1414
9BAA82B31D451A0E00E5B98A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9BAA82B21D451A0E00E5B98A /* Assets.xcassets */; };
1515
9BAA82B61D451A0E00E5B98A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9BAA82B41D451A0E00E5B98A /* LaunchScreen.storyboard */; };
16+
E59118CB1D9B84FE00F25FF6 /* NSObject+DeallocBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = E59118CA1D9B84FE00F25FF6 /* NSObject+DeallocBlock.m */; };
1617
/* End PBXBuildFile section */
1718

1819
/* Begin PBXFileReference section */
@@ -26,6 +27,8 @@
2627
9BAA82B21D451A0E00E5B98A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
2728
9BAA82B51D451A0E00E5B98A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
2829
9BAA82B71D451A0E00E5B98A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
30+
E59118C91D9B84FE00F25FF6 /* NSObject+DeallocBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+DeallocBlock.h"; sourceTree = "<group>"; };
31+
E59118CA1D9B84FE00F25FF6 /* NSObject+DeallocBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+DeallocBlock.m"; sourceTree = "<group>"; };
2932
/* End PBXFileReference section */
3033

3134
/* Begin PBXFrameworksBuildPhase section */
@@ -58,6 +61,8 @@
5861
9BAA82A51D451A0E00E5B98A /* RunloopAndThread */ = {
5962
isa = PBXGroup;
6063
children = (
64+
E59118C91D9B84FE00F25FF6 /* NSObject+DeallocBlock.h */,
65+
E59118CA1D9B84FE00F25FF6 /* NSObject+DeallocBlock.m */,
6166
9BAA82A91D451A0E00E5B98A /* AppDelegate.h */,
6267
9BAA82AA1D451A0E00E5B98A /* AppDelegate.m */,
6368
9BAA82AC1D451A0E00E5B98A /* ViewController.h */,
@@ -110,7 +115,7 @@
110115
TargetAttributes = {
111116
9BAA82A21D451A0E00E5B98A = {
112117
CreatedOnToolsVersion = 7.3.1;
113-
DevelopmentTeam = U2HX3RFD94;
118+
DevelopmentTeam = RN42P92PY7;
114119
};
115120
};
116121
};
@@ -150,6 +155,7 @@
150155
isa = PBXSourcesBuildPhase;
151156
buildActionMask = 2147483647;
152157
files = (
158+
E59118CB1D9B84FE00F25FF6 /* NSObject+DeallocBlock.m in Sources */,
153159
9BAA82AE1D451A0E00E5B98A /* ViewController.m in Sources */,
154160
9BAA82AB1D451A0E00E5B98A /* AppDelegate.m in Sources */,
155161
9BAA82A81D451A0E00E5B98A /* main.m in Sources */,
@@ -264,6 +270,7 @@
264270
isa = XCBuildConfiguration;
265271
buildSettings = {
266272
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
273+
DEVELOPMENT_TEAM = RN42P92PY7;
267274
INFOPLIST_FILE = RunloopAndThread/Info.plist;
268275
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
269276
PRODUCT_BUNDLE_IDENTIFIER = baidu.RunloopAndThread;
@@ -275,6 +282,7 @@
275282
isa = XCBuildConfiguration;
276283
buildSettings = {
277284
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
285+
DEVELOPMENT_TEAM = RN42P92PY7;
278286
INFOPLIST_FILE = RunloopAndThread/Info.plist;
279287
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
280288
PRODUCT_BUNDLE_IDENTIFIER = baidu.RunloopAndThread;
@@ -301,6 +309,7 @@
301309
9BAA82BC1D451A0E00E5B98A /* Release */,
302310
);
303311
defaultConfigurationIsVisible = 0;
312+
defaultConfigurationName = Release;
304313
};
305314
/* End XCConfigurationList section */
306315
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//
2+
// NSObject+DeallocBlock.h
3+
// pengpeng
4+
//
5+
// Created by jianwei.chen on 15/9/6.
6+
// Copyright (c) 2015年 AsiaInnovations. All rights reserved.
7+
//
8+
9+
#import <Foundation/Foundation.h>
10+
11+
@interface NSObject (DeallocBlock)
12+
13+
-(void)runAtDealloc:(dispatch_block_t)block;
14+
@end
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//
2+
// NSObject+DeallocBlock.m
3+
// pengpeng
4+
//
5+
// Created by jianwei.chen on 15/9/6.
6+
// Copyright (c) 2015年 AsiaInnovations. All rights reserved.
7+
//
8+
9+
#import "NSObject+DeallocBlock.h"
10+
#import <objc/message.h>
11+
12+
@interface NBDeallocBlockExecutor : NSObject{
13+
dispatch_block_t _block;
14+
}
15+
- (id)initWithBlock:(dispatch_block_t)block;
16+
@end
17+
18+
@implementation NBDeallocBlockExecutor
19+
- (id)initWithBlock:(dispatch_block_t)aBlock
20+
{
21+
self = [super init];
22+
if (self) {
23+
_block = [aBlock copy];
24+
}
25+
return self;
26+
}
27+
- (void)dealloc
28+
{
29+
_block ? _block() : nil;
30+
}
31+
@end
32+
33+
34+
static char *dealloc_key;
35+
@implementation NSObject (DeallocBlock)
36+
37+
-(void)runAtDealloc:(dispatch_block_t)block
38+
{
39+
if(block){
40+
NBDeallocBlockExecutor *executor = [[NBDeallocBlockExecutor alloc] initWithBlock:block];
41+
objc_setAssociatedObject(self, &dealloc_key, executor, OBJC_ASSOCIATION_RETAIN);//不要强应用
42+
}
43+
}
44+
45+
@end

RunloopAndThread/RunloopAndThread/ViewController.m

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//
88

99
#import "ViewController.h"
10+
#import "NSObject+DeallocBlock.h"
1011

1112
@interface ViewController ()
1213

@@ -18,23 +19,35 @@ @interface ViewController ()
1819

1920
@implementation ViewController
2021

22+
2123
- (void)viewDidLoad {
2224
[super viewDidLoad];
23-
// [self memoryTest];
25+
[self memoryTest];
26+
NSLog(@"test");
2427
// [self runloopTest];
2528
}
2629

2730
#pragma --mark 内存占用测试
2831
- (void)memoryTest {
2932
for (int i = 0; i < 100000; ++i) {
33+
//总结:test At: xcode8,ios 9.3.4
34+
//1,当用CFRunLoopRun(),然后调用CFRunLoopStop,此方法是后果会输出current thread,thread dealloc,current thread,thread dealloc ...所以不会用内存问题
35+
//2,当用 [runLoop run];,然后调用CFRunLoopStop,此方法会current thread,current thread,... 最后输出[NSThread start]: Thread creation failed with error 35.然后app卡住,然后app crash. 内存不会暴增。但是线程无法销毁
36+
//3,当用 [runLoop runMode:NSRunLoopCommonModes beforeDate:[NSDate distantFuture]];,然后调用CFRunLoopStop,此方法会。[ViewController performSelector:onThread:withObject:waitUntilDone:modes:]: target thread exited while waiting for the perform' crash。是因为 [runLoop runMode:NSRunLoopCommonModes beforeDate:[NSDate distantFuture]]; 无法阻塞线程,所以线程很快执行完run 方法。然后线程exit,导致奔溃(在一个退出的线程,当然这个时候线程没有释放,执行方法奔溃)
37+
3038
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
39+
[thread runAtDealloc:^{
40+
NSLog(@"thread dealloc");
41+
}];
3142
[thread start];
3243
[self performSelector:@selector(stopThread) onThread:thread withObject:nil waitUntilDone:YES];
3344
}
45+
NSLog(@"test over");
3446
}
3547

3648
- (void)stopThread {
3749
CFRunLoopStop(CFRunLoopGetCurrent());
50+
// [[NSRunLoop currentRunLoop] removePort:self.emptyPort forMode:NSDefaultRunLoopMode];
3851
NSThread *thread = [NSThread currentThread];
3952
[thread cancel];
4053
}
@@ -49,8 +62,9 @@ - (void)run {
4962
[runLoop addPort:self.emptyPort forMode:NSDefaultRunLoopMode];
5063
// 下面这两种写法都不可取
5164
// [runLoop run];
52-
// [runLoop runMode:NSRunLoopCommonModes beforeDate:[NSDate distantFuture]];
53-
CFRunLoopRun();
65+
[runLoop runMode:NSRunLoopCommonModes beforeDate:[NSDate distantFuture]];
66+
// CFRunLoopRun();
67+
NSLog(@"run over");
5468
}
5569
}
5670

0 commit comments

Comments
 (0)