Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jezz
JJException
Commits
a0f3ad78
Commit
a0f3ad78
authored
6 years ago
by
李杰
Browse files
Options
Download
Email Patches
Plain Diff
Refactor the KVO
parent
0c4cca0e
master
github/fork/misaka14/master
github/fork/superClown/fixios15
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.9
0.1.8
No related merge requests found
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
JJException.podspec
+2
-2
JJException.podspec
JJException.xcodeproj/project.xcworkspace/xcuserdata/jezz.xcuserdatad/UserInterfaceState.xcuserstate
+0
-0
...cuserdata/jezz.xcuserdatad/UserInterfaceState.xcuserstate
JJException.xcodeproj/xcuserdata/jezz.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
+5
-53
...ata/jezz.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
JJException/PushViewController.m
+1
-0
JJException/PushViewController.m
JJException/Source/MRC/NSObject+KVOCrash.m
+77
-11
JJException/Source/MRC/NSObject+KVOCrash.m
JJException/Source/Swizzle/NSObject+SwizzleHook.h
+53
-0
JJException/Source/Swizzle/NSObject+SwizzleHook.h
JJException/Source/Swizzle/NSObject+SwizzleHook.m
+57
-0
JJException/Source/Swizzle/NSObject+SwizzleHook.m
JJExceptionHookAPI.md
+35
-0
JJExceptionHookAPI.md
JJExceptionPrinciple.md
+4
-0
JJExceptionPrinciple.md
with
234 additions
and
66 deletions
+234
-66
JJException.podspec
+
2
-
2
View file @
a0f3ad78
...
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
...
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
#
#
s
.
name
=
"JJException"
s
.
name
=
"JJException"
s
.
version
=
"0.1.
7
"
s
.
version
=
"0.1.
8
"
s
.
summary
=
"Handle the objective-c crash exception."
s
.
summary
=
"Handle the objective-c crash exception."
# This description is used to generate tags and improve search results.
# This description is used to generate tags and improve search results.
...
@@ -69,7 +69,7 @@ Pod::Spec.new do |s|
...
@@ -69,7 +69,7 @@ Pod::Spec.new do |s|
# When using multiple platforms
# When using multiple platforms
s
.
ios
.
deployment_target
=
"8.0"
s
.
ios
.
deployment_target
=
"8.0"
s
.
osx
.
deployment_target
=
"10.
7
"
s
.
osx
.
deployment_target
=
"10.
8
"
s
.
watchos
.
deployment_target
=
"2.0"
s
.
watchos
.
deployment_target
=
"2.0"
s
.
tvos
.
deployment_target
=
"9.0"
s
.
tvos
.
deployment_target
=
"9.0"
...
...
This diff is collapsed.
Click to expand it.
JJException.xcodeproj/project.xcworkspace/xcuserdata/jezz.xcuserdatad/UserInterfaceState.xcuserstate
+
0
-
0
View file @
a0f3ad78
No preview for this file type
This diff is collapsed.
Click to expand it.
JJException.xcodeproj/xcuserdata/jezz.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
+
5
-
53
View file @
a0f3ad78
...
@@ -27,61 +27,13 @@
...
@@ -27,61 +27,13 @@
shouldBeEnabled =
"Yes"
shouldBeEnabled =
"Yes"
ignoreCount =
"0"
ignoreCount =
"0"
continueAfterRunningActions =
"No"
continueAfterRunningActions =
"No"
filePath =
"JJException/Source/
MRC/NSObject+KVOCrash
.m"
filePath =
"JJException/Source/
DeallocBlock/NSObject+DeallocBlock
.m"
timestampString =
"564
488427.585709
"
timestampString =
"564
822196.511668
"
startingColumnNumber =
"9223372036854775807"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"133"
startingLineNumber =
"26"
endingLineNumber =
"133"
endingLineNumber =
"26"
landmarkName =
"-clearKVOData"
landmarkName =
"-dealloc"
landmarkType =
"7"
>
<Locations>
<Location
shouldBeEnabled =
"Yes"
ignoreCount =
"0"
continueAfterRunningActions =
"No"
symbolName =
"-[KVOObjectContainer clearKVOData]"
moduleName =
"JJException"
usesParentBreakpointCondition =
"Yes"
urlString =
"file:///Users/jezz/git_project/JJExceptionGithub/JJException/Source/MRC/NSObject+KVOCrash.m"
timestampString =
"564488398.348398"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"133"
endingLineNumber =
"133"
offsetFromSymbolStart =
"55"
>
</Location>
<Location
shouldBeEnabled =
"Yes"
ignoreCount =
"0"
continueAfterRunningActions =
"No"
symbolName =
"-[KVOObjectContainer clearKVOData]"
moduleName =
"JJException"
usesParentBreakpointCondition =
"Yes"
urlString =
"file:///Users/jezz/git_project/JJExceptionGithub/JJException/Source/MRC/NSObject+KVOCrash.m"
timestampString =
"564488398.350692"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"133"
endingLineNumber =
"133"
offsetFromSymbolStart =
"65"
>
</Location>
</Locations>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID =
"Xcode.Breakpoint.FileBreakpoint"
>
<BreakpointContent
shouldBeEnabled =
"Yes"
ignoreCount =
"0"
continueAfterRunningActions =
"No"
filePath =
"JJException/Source/MRC/NSObject+KVOCrash.m"
timestampString =
"564488427.587878"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"244"
endingLineNumber =
"244"
landmarkName =
"-kvo_hookDealloc"
landmarkType =
"7"
>
landmarkType =
"7"
>
</BreakpointContent>
</BreakpointContent>
</BreakpointProxy>
</BreakpointProxy>
...
...
This diff is collapsed.
Click to expand it.
JJException/PushViewController.m
+
1
-
0
View file @
a0f3ad78
...
@@ -56,6 +56,7 @@
...
@@ -56,6 +56,7 @@
dispatch_after
(
dispatch_time
(
DISPATCH_TIME_NOW
,
(
int64_t
)(
2
*
NSEC_PER_SEC
)),
dispatch_get_main_queue
(),
^
{
dispatch_after
(
dispatch_time
(
DISPATCH_TIME_NOW
,
(
int64_t
)(
2
*
NSEC_PER_SEC
)),
dispatch_get_main_queue
(),
^
{
_kvoObserver
=
nil
;
_kvoObserver
=
nil
;
self
.
demoString1
=
@"11"
;
});
});
dispatch_after
(
dispatch_time
(
DISPATCH_TIME_NOW
,
(
int64_t
)(
6
*
NSEC_PER_SEC
)),
dispatch_get_main_queue
(),
^
{
dispatch_after
(
dispatch_time
(
DISPATCH_TIME_NOW
,
(
int64_t
)(
6
*
NSEC_PER_SEC
)),
dispatch_get_main_queue
(),
^
{
...
...
This diff is collapsed.
Click to expand it.
JJException/Source/MRC/NSObject+KVOCrash.m
+
77
-
11
View file @
a0f3ad78
...
@@ -13,6 +13,7 @@
...
@@ -13,6 +13,7 @@
#import "JJExceptionProxy.h"
#import "JJExceptionProxy.h"
static
const
char
DeallocKVOKey
;
static
const
char
DeallocKVOKey
;
static
const
char
ObserverDeallocKVOKey
;
/**
/**
Record the kvo object
Record the kvo object
...
@@ -51,6 +52,7 @@ static const char DeallocKVOKey;
...
@@ -51,6 +52,7 @@ static const char DeallocKVOKey;
@end
@end
@interface
KVOObjectContainer
:
NSObject
@interface
KVOObjectContainer
:
NSObject
/**
/**
...
@@ -129,7 +131,7 @@ static const char DeallocKVOKey;
...
@@ -129,7 +131,7 @@ static const char DeallocKVOKey;
[
super
dealloc
];
[
super
dealloc
];
}
}
-
(
void
)
clea
r
KVOData
{
-
(
void
)
clea
n
KVOData
{
for
(
KVOObjectItem
*
item
in
self
.
kvoObjectSet
)
{
for
(
KVOObjectItem
*
item
in
self
.
kvoObjectSet
)
{
#pragma clang diagnostic push
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
#pragma clang diagnostic ignored "-Wundeclared-selector"
...
@@ -151,14 +153,66 @@ static const char DeallocKVOKey;
...
@@ -151,14 +153,66 @@ static const char DeallocKVOKey;
@end
@end
@interface
JJObserverContainer
:
NSObject
@property
(
nonatomic
,
readwrite
,
strong
)
NSHashTable
*
observers
;
/**
Associated owner object
*/
@property
(
nonatomic
,
readwrite
,
unsafe_unretained
)
NSObject
*
whichObject
;
-
(
void
)
addObserver
:(
KVOObjectItem
*
)
observer
;
-
(
void
)
removeObserver
:(
KVOObjectItem
*
)
observer
;
@end
@implementation
JJObserverContainer
-
(
instancetype
)
init
{
self
=
[
super
init
];
if
(
self
)
{
self
.
observers
=
[
NSHashTable
hashTableWithOptions
:
NSMapTableWeakMemory
];
}
return
self
;
}
-
(
void
)
addObserver
:(
KVOObjectItem
*
)
observer
{
@synchronized
(
self
)
{
[
self
.
observers
addObject
:
observer
];
}
}
-
(
void
)
removeObserver
:(
KVOObjectItem
*
)
observer
{
@synchronized
(
self
)
{
[
self
.
observers
removeObject
:
observer
];
}
}
-
(
void
)
cleanObservers
{
for
(
KVOObjectItem
*
item
in
self
.
observers
)
{
[
self
.
whichObject
removeObserver
:
item
.
observer
forKeyPath
:
item
.
keyPath
];
}
}
-
(
void
)
dealloc
{
self
.
whichObject
=
nil
;
[
self
.
observers
release
];
[
super
dealloc
];
}
@end
@implementation
NSObject
(
KVOCrash
)
@implementation
NSObject
(
KVOCrash
)
+
(
void
)
jj_swizzleKVOCrash
{
+
(
void
)
jj_swizzleKVOCrash
{
swizzleInstanceMethod
([
self
class
],
@selector
(
addObserver
:
forKeyPath
:
options
:
context
:
),
@selector
(
hookAddObserver
:
forKeyPath
:
options
:
context
:
));
swizzleInstanceMethod
([
self
class
],
@selector
(
addObserver
:
forKeyPath
:
options
:
context
:
),
@selector
(
hookAddObserver
:
forKeyPath
:
options
:
context
:
));
swizzleInstanceMethod
([
self
class
],
@selector
(
removeObserver
:
forKeyPath
:
),
@selector
(
hookRemoveObserver
:
forKeyPath
:
));
swizzleInstanceMethod
([
self
class
],
@selector
(
removeObserver
:
forKeyPath
:
),
@selector
(
hookRemoveObserver
:
forKeyPath
:
));
swizzleInstanceMethod
([
self
class
],
@selector
(
removeObserver
:
forKeyPath
:
context
:
),
@selector
(
hookRemoveObserver
:
forKeyPath
:
context
:
));
swizzleInstanceMethod
([
self
class
],
@selector
(
removeObserver
:
forKeyPath
:
context
:
),
@selector
(
hookRemoveObserver
:
forKeyPath
:
context
:
));
//Swizzle kvo dealloc
swizzleInstanceMethod
([
self
class
],
@selector
(
dealloc
),
@selector
(
kvo_hookDealloc
));
}
}
-
(
void
)
hookAddObserver
:(
NSObject
*
)
observer
forKeyPath
:(
NSString
*
)
keyPath
options
:(
NSKeyValueObservingOptions
)
options
context
:(
void
*
)
context
{
-
(
void
)
hookAddObserver
:(
NSObject
*
)
observer
forKeyPath
:(
NSString
*
)
keyPath
options
:(
NSKeyValueObservingOptions
)
options
context
:(
void
*
)
context
{
...
@@ -191,7 +245,22 @@ static const char DeallocKVOKey;
...
@@ -191,7 +245,22 @@ static const char DeallocKVOKey;
[
self
hookAddObserver
:
observer
forKeyPath
:
keyPath
options
:
options
context
:
context
];
[
self
hookAddObserver
:
observer
forKeyPath
:
keyPath
options
:
options
context
:
context
];
}
}
JJObserverContainer
*
observerContainer
=
objc_getAssociatedObject
(
observer
,
&
ObserverDeallocKVOKey
);
if
(
!
observerContainer
)
{
observerContainer
=
[
JJObserverContainer
new
];
[
observerContainer
setWhichObject
:
self
];
[
observerContainer
addObserver
:
item
];
objc_setAssociatedObject
(
observer
,
&
ObserverDeallocKVOKey
,
observerContainer
,
OBJC_ASSOCIATION_RETAIN
);
[
observerContainer
release
];
}
else
{
[
observerContainer
addObserver
:
item
];
}
[
item
release
];
[
item
release
];
jj_swizzleDeallocIfNeeded
(
self
.
class
);
jj_swizzleDeallocIfNeeded
(
observer
.
class
);
}
}
-
(
void
)
hookRemoveObserver
:(
NSObject
*
)
observer
forKeyPath
:(
NSString
*
)
keyPath
context
:(
void
*
)
context
{
-
(
void
)
hookRemoveObserver
:(
NSObject
*
)
observer
forKeyPath
:(
NSString
*
)
keyPath
context
:(
void
*
)
context
{
...
@@ -236,19 +305,16 @@ static const char DeallocKVOKey;
...
@@ -236,19 +305,16 @@ static const char DeallocKVOKey;
/**
/**
* Hook the kvo object dealloc and to clean the kvo array,
* Hook the kvo object dealloc and to clean the kvo array
* And show the more kvo object info to the user
*/
*/
-
(
void
)
kvo_hookDealloc
{
-
(
void
)
jj_cleanKVO
{
KVOObjectContainer
*
objectContainer
=
objc_getAssociatedObject
(
self
,
&
DeallocKVOKey
);
KVOObjectContainer
*
objectContainer
=
objc_getAssociatedObject
(
self
,
&
DeallocKVOKey
);
[
objectContainer
cleanKVOData
];
if
(
objectContainer
)
{
JJObserverContainer
*
observerContainer
=
objc_getAssociatedObject
(
self
,
&
ObserverDeallocKVOKey
);
[
objectContainer
clearKVOData
];
[
observerContainer
cleanObservers
];
}
//Invoke the origin dealloc
[
self
kvo_hookDealloc
];
}
}
@end
@end
This diff is collapsed.
Click to expand it.
JJException/Source/Swizzle/NSObject+SwizzleHook.h
+
53
-
0
View file @
a0f3ad78
...
@@ -8,6 +8,11 @@
...
@@ -8,6 +8,11 @@
#import <Foundation/Foundation.h>
#import <Foundation/Foundation.h>
/*
* JJSwizzledIMPBlock assist variable
*/
typedef
void
(
*
JJSwizzleOriginalIMP
)(
void
/* id, SEL, ... */
);
typedef
void
(
*
JJSwizzleOriginalIMP
)(
void
/* id, SEL, ... */
);
@interface
JJSwizzleObject
:
NSObject
@interface
JJSwizzleObject
:
NSObject
...
@@ -20,16 +25,64 @@ typedef void (*JJSwizzleOriginalIMP)(void /* id, SEL, ... */ );
...
@@ -20,16 +25,64 @@ typedef void (*JJSwizzleOriginalIMP)(void /* id, SEL, ... */ );
typedef
id
(
^
JJSwizzledIMPBlock
)(
JJSwizzleObject
*
swizzleInfo
);
typedef
id
(
^
JJSwizzledIMPBlock
)(
JJSwizzleObject
*
swizzleInfo
);
/*
* JJSwizzledIMPBlock assist variable
*/
/**
* Swizzle Class Method
@param cls Class
@param originSelector originSelector
@param swizzleSelector swizzleSelector
*/
void
swizzleClassMethod
(
Class
cls
,
SEL
originSelector
,
SEL
swizzleSelector
);
void
swizzleClassMethod
(
Class
cls
,
SEL
originSelector
,
SEL
swizzleSelector
);
/**
* Swizzle Instance Class Method
@param cls Class
@param originSelector originSelector
@param swizzleSelector swizzleSelector
*/
void
swizzleInstanceMethod
(
Class
cls
,
SEL
originSelector
,
SEL
swizzleSelector
);
void
swizzleInstanceMethod
(
Class
cls
,
SEL
originSelector
,
SEL
swizzleSelector
);
/**
* Only swizzle the current class,not swizzle all class
* perform jj_cleanKVO selector before the origin dealloc
@param class Class
*/
void
jj_swizzleDeallocIfNeeded
(
Class
class
);
/**
Swizzle the NSObject Extension
*/
@interface
NSObject
(
SwizzleHook
)
@interface
NSObject
(
SwizzleHook
)
/**
Swizzle Class Method
@param originSelector originSelector
@param swizzleSelector swizzleSelector
*/
+
(
void
)
jj_swizzleClassMethod
:(
SEL
)
originSelector
withSwizzleMethod
:(
SEL
)
swizzleSelector
;
+
(
void
)
jj_swizzleClassMethod
:(
SEL
)
originSelector
withSwizzleMethod
:(
SEL
)
swizzleSelector
;
/**
Swizzle Instance Method
@param originSelector originSelector
@param swizzleSelector swizzleSelector
*/
-
(
void
)
jj_swizzleInstanceMethod
:(
SEL
)
originSelector
withSwizzleMethod
:(
SEL
)
swizzleSelector
;
-
(
void
)
jj_swizzleInstanceMethod
:(
SEL
)
originSelector
withSwizzleMethod
:(
SEL
)
swizzleSelector
;
/**
Swizzle instance method to the block target
@param originSelector originSelector
@param swizzledBlock block
*/
-
(
void
)
jj_swizzleInstanceMethod
:(
SEL
)
originSelector
withSwizzledBlock
:(
JJSwizzledIMPBlock
)
swizzledBlock
;
-
(
void
)
jj_swizzleInstanceMethod
:(
SEL
)
originSelector
withSwizzledBlock
:(
JJSwizzledIMPBlock
)
swizzledBlock
;
@end
@end
This diff is collapsed.
Click to expand it.
JJException/Source/Swizzle/NSObject+SwizzleHook.m
+
57
-
0
View file @
a0f3ad78
...
@@ -8,10 +8,13 @@
...
@@ -8,10 +8,13 @@
#import "NSObject+SwizzleHook.h"
#import "NSObject+SwizzleHook.h"
#import <objc/runtime.h>
#import <objc/runtime.h>
#import <objc/message.h>
#import <libkern/OSAtomic.h>
#import <libkern/OSAtomic.h>
typedef
IMP
(
^
JJSWizzleImpProvider
)(
void
);
typedef
IMP
(
^
JJSWizzleImpProvider
)(
void
);
static
const
char
jjSwizzledDeallocKey
;
@interface
JJSwizzleObject
()
@interface
JJSwizzleObject
()
@property
(
nonatomic
,
readwrite
,
copy
)
JJSWizzleImpProvider
impProviderBlock
;
@property
(
nonatomic
,
readwrite
,
copy
)
JJSWizzleImpProvider
impProviderBlock
;
@property
(
nonatomic
,
readwrite
,
assign
)
SEL
selector
;
@property
(
nonatomic
,
readwrite
,
assign
)
SEL
selector
;
...
@@ -88,6 +91,60 @@ void swizzleInstanceMethod(Class cls, SEL originSelector, SEL swizzleSelector){
...
@@ -88,6 +91,60 @@ void swizzleInstanceMethod(Class cls, SEL originSelector, SEL swizzleSelector){
}
}
}
}
// a class doesn't need dealloc swizzled if it or a superclass has been swizzled already
BOOL
jj_requiresDeallocSwizzle
(
Class
class
)
{
BOOL
swizzled
=
NO
;
for
(
Class
currentClass
=
class
;
!
swizzled
&&
currentClass
!=
nil
;
currentClass
=
class_getSuperclass
(
currentClass
)
)
{
swizzled
=
[
objc_getAssociatedObject
(
currentClass
,
&
jjSwizzledDeallocKey
)
boolValue
];
}
return
!
swizzled
;
}
void
jj_swizzleDeallocIfNeeded
(
Class
class
)
{
static
SEL
deallocSEL
=
NULL
;
static
SEL
cleanupSEL
=
NULL
;
static
dispatch_once_t
onceToken
;
dispatch_once
(
&
onceToken
,
^
{
deallocSEL
=
sel_getUid
(
"dealloc"
);
cleanupSEL
=
sel_getUid
(
"jj_cleanKVO"
);
});
@synchronized
(
class
)
{
if
(
!
jj_requiresDeallocSwizzle
(
class
)
)
{
return
;
}
objc_setAssociatedObject
(
class
,
&
jjSwizzledDeallocKey
,
@
(
YES
),
OBJC_ASSOCIATION_RETAIN_NONATOMIC
);
}
Method
dealloc
=
class_getInstanceMethod
(
class
,
deallocSEL
);
if
(
dealloc
==
NULL
)
{
Class
superclass
=
class_getSuperclass
(
class
);
class_addMethod
(
class
,
deallocSEL
,
imp_implementationWithBlock
(
^
(
__unsafe_unretained
id
self
)
{
((
void
(
*
)(
id
,
SEL
))
objc_msgSend
)(
self
,
cleanupSEL
);
struct
objc_super
superStruct
=
(
struct
objc_super
){
self
,
superclass
};
((
void
(
*
)(
struct
objc_super
*
,
SEL
))
objc_msgSendSuper
)(
&
superStruct
,
deallocSEL
);
}),
method_getTypeEncoding
(
dealloc
));
}
else
{
__block
IMP
deallocIMP
=
method_setImplementation
(
dealloc
,
imp_implementationWithBlock
(
^
(
__unsafe_unretained
id
self
)
{
((
void
(
*
)(
id
,
SEL
))
objc_msgSend
)(
self
,
cleanupSEL
);
((
void
(
*
)(
id
,
SEL
))
deallocIMP
)(
self
,
deallocSEL
);
}));
}
}
@implementation
NSObject
(
SwizzleHook
)
@implementation
NSObject
(
SwizzleHook
)
void
__JJ_SWIZZLE_BLOCK
(
Class
classToSwizzle
,
SEL
selector
,
JJSwizzledIMPBlock
impBlock
){
void
__JJ_SWIZZLE_BLOCK
(
Class
classToSwizzle
,
SEL
selector
,
JJSwizzledIMPBlock
impBlock
){
...
...
This diff is collapsed.
Click to expand it.
JJExceptionHookAPI.md
+
35
-
0
View file @
a0f3ad78
...
@@ -36,6 +36,29 @@
...
@@ -36,6 +36,29 @@
- (NSString *)stringByAppendingString:(NSString *)aString;
- (NSString *)stringByAppendingString:(NSString *)aString;
```
```
*
NSAttributedString
```
- (instancetype)initWithString:(NSString *)str;
- (NSAttributedString *)attributedSubstringFromRange:(NSRange)range;
- (nullable id)attribute:(NSAttributedStringKey)attrName atIndex:(NSUInteger)location effectiveRange:(nullable NSRangePointer)range;
- (void)enumerateAttribute:(NSAttributedStringKey)attrName inRange:(NSRange)enumerationRange options:(NSAttributedStringEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(id _Nullable value, NSRange range, BOOL *stop))block;
- (void)enumerateAttributesInRange:(NSRange)enumerationRange options:(NSAttributedStringEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(NSDictionary<NSAttributedStringKey, id> *attrs, NSRange range, BOOL *stop))block;
```
*
NSMutableAttributedString
```
- (instancetype)initWithString:(NSString *)str;
- (instancetype)initWithString:(NSString *)str attributes:(nullable NSDictionary<NSAttributedStringKey, id> *)attrs;
- (void)addAttribute:(NSAttributedStringKey)name value:(id)value range:(NSRange)range;
- (void)addAttributes:(NSDictionary<NSAttributedStringKey, id> *)attrs range:(NSRange)range;
- (void)removeAttribute:(NSAttributedStringKey)name range:(NSRange)range;
- (void)replaceCharactersInRange:(NSRange)range withAttributedString:(NSAttributedString *)attrString;
- (void)deleteCharactersInRange:(NSRange)range;
- (void)setAttributedString:(NSAttributedString *)attrString;
```
*
NSArray
*
NSArray
```
```
...
@@ -82,3 +105,15 @@
...
@@ -82,3 +105,15 @@
- (void) addObject:(id)object;
- (void) addObject:(id)object;
- (void) removeObject:(id)object;
- (void) removeObject:(id)object;
```
```
*
NSTimer
```
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
```
*
NSNotificationCenter
```
- (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject;
```
This diff is collapsed.
Click to expand it.
JJExceptionPrinciple.md
+
4
-
0
View file @
a0f3ad78
...
@@ -199,6 +199,10 @@ KVO在以下情况会导致闪退:
...
@@ -199,6 +199,10 @@ KVO在以下情况会导致闪退:
所以在没找到更好的办法,只能Swizzle dealloc方法,先清理kvo数据,再执行origin dealloc,不过这样就有个细节做不到,无法提示那些keyPath忘记清理.
所以在没找到更好的办法,只能Swizzle dealloc方法,先清理kvo数据,再执行origin dealloc,不过这样就有个细节做不到,无法提示那些keyPath忘记清理.
__2018/11/25__
Swizzle dealloc影响面相对偏广,后续找了一种只针对需要KVO需求类的Swizzle,当前类用AssociatedObject来记住状态,如果Swizzle过就直接返回,另外还加强KVO的健壮性,监听了observer状态,在宿主还没释放,observer先释放,需要要对observer对应的keyPath对应的清理.
## NSTimer
## NSTimer
NSTimer存在以下问题:
NSTimer存在以下问题:
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment