WKWebView
WKWebView
will disappear white screen.WKWebView
is a multi process component, WebContent Process will be crashed. At the same time, WKWebView
.URL will be nil. To use below function to reload webview.- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView API_AVAILABLE(macosx(10.11), ios(9.0)){
[self.webView reload];
}
複製代碼
NSURLProcotol
, it will cause post-request lost thier request-body and request-bodystream.WKWebView
cookie lost is the same question about "lost request-body".WKWebView
// step 1
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
//step 2
- (void)webView:(WKWebView *)webView didCommitNavigation:( WKNavigation *)navigation;
// step 3
+ (BOOL)canInitWithRequest:(NSURLRequest *)request;
// step 4
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request;
// step 5
- (void)startLoading;
// step 6
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
複製代碼
UIView
-(void)reloadData;
to selected or unselected TableViewCell to refresh the didslected-cell will appear cell-list flashing.reloadSection:withRowAnimation:
or reloadRow:withRowAnimation:
to refresh relateive cell.//First function
[UIView performWithoutAnimation:^{
[collectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:index inSection:0]]];
}];
//Second function
[UIView animateWithDuration:0 animations:^{
[collectionView performBatchUpdates:^{
[collectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:index inSection:0]]];
} completion:nil];
}];
//Three function
[UIView setAnimationsEnabled:NO];
[self.trackPanel performBatchUpdates:^{
[collectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:index inSection:0]]];
} completion:^(BOOL finished) {
[UIView setAnimationsEnabled:YES];
}];
複製代碼
drawRect
shouldRasterize、masks、shadows、edge antialiasing、group opacity、cornerRadius、gradual change
. Pay Attention to, after iOS9.0 UIImageView will not cause offscreen-rendered.alloc-init
,dispatch_once_t onceToken
,copy
,mutableCopy
,these four function should create the same memory address.@property = ivar + getter + setter, is combination of instance variables and setter/getter method.html
Keywords about property: atomic and nonatomic, assign, strong, copy, weak, unsafe_unretained.ios
atomic - nonatomic
:Compare with atomic, nonatomic is faster.Because it's faster, it cause unsafer relatively. If want to make sure the thread safe, atomic is unreliable, you should use synchrolock. such as,// synchrolock, to be thread safe
- (void)setSomeString:(NSString *)someString {
@synchronized(self) {
_someString = someString;
}
}
//concurrent queue
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
- (NSString *)someString {
__block NSString *localSomeString;
dispatch_sync(_queue, ^{
localSomeString = _someString;
});
return localSomeString;
}
複製代碼
The ideal solution is, Getter function realized by dispatch_sync(dispatch_queue_t queue, dispatch_block_t blcok);
, And setter function realized by dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t blcok);
web
link to 重識iOS之Propertyajax
interviewobjective-c
dispatch_queue_t
dispatch_block_t
複製代碼
// GCD 用同步方法執行任務
dispatch_sync(dispatch_queue_t queue, dispatch_block_t blcok);
// GCD 用異步方法執行任務
dispatch_async(dispatch_queue_t queue, dispatch_block_t blcok);
複製代碼
sync
:Only run in current thread, couldn't create thread.async
:Excute in new thread, can create new thread.dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t blcok);
dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t blcok);
複製代碼
dispatch_barrier_sync
:Upload a barrier should wait for pervious barrier excuted, then excute the barrier. It's excute in main thread.dispatch_barrier_async
:Upload a barrier excute in async, and it will excute if you upload immediately.------- Example below -------shell
//concurrent queue Barrier
- (void)concurrentQueue2Barrier
{
dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"Task 0 %d",i);
}];
});
dispatch_async(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"Task 1 %d",i);
}];
});
NSLog(@"Sync barrier start😊");
dispatch_barrier_sync(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"Sync barrier, %@",[NSThread currentThread]);
}];
});
NSLog(@"Sync barrier end😊");
dispatch_async(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"Task 2 %d",i);
}];
});
dispatch_async(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"Task 3 %d",i);
}];
});
NSLog(@"ASync barrier start 😄");
dispatch_barrier_async(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"ASync barrier %@",[NSThread currentThread]);
}];
});
NSLog(@"ASync barrier end 😄");
dispatch_async(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"Task 4 %d",i);
}];
});
dispatch_async(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"Task 5 %d",i);
}];
});
}
- (void)forNumIncrementCondition:(NSUInteger )num actionBlock:(void(^)(int i))actionBlcok
{
for (int a = 0; a < num; a ++)
{
if (actionBlcok) {
actionBlcok(a);
}
}
}
<!--Barrier[5141:1319243] Sync Barrier start😊-->
<!--Barrier[5141:1319371] Task0 0-->
<!--Barrier[5141:1322592] Task1 0-->
<!--Barrier[5141:1319371] Task0 1-->
<!--Barrier[5141:1322592] Task1 1-->
<!--Barrier[5141:1319371] Task0 2-->
<!--Barrier[5141:1322592] Task1 2-->
<!--Barrier[5141:1319371] Task0 3-->
<!--Barrier[5141:1322592] Task1 3-->
<!--Barrier[5141:1319371] Task0 4-->
<!--Barrier[5141:1322592] Task1 4-->
<!--Barrier[5141:1319243] Sync Barrier, <NSThread: 0x60800006f300>{number = 1, name = main}-->
<!--Barrier[5141:1319243] Sync Barrier, <NSThread: 0x60800006f300>{number = 1, name = main}-->
<!--Barrier[5141:1319243] Sync Barrier, <NSThread: 0x60800006f300>{number = 1, name = main}-->
<!--Barrier[5141:1319243] Sync Barrier, <NSThread: 0x60800006f300>{number = 1, name = main}-->
<!--Barrier[5141:1319243] Sync Barrier, <NSThread: 0x60800006f300>{number = 1, name = main}-->
<!--Barrier[5141:1319243] Sync Barrier end😊-->
<!--Barrier[5141:1319243] ASync Barrier start 😄-->
<!--Barrier[5141:1319371] Task3 0-->
<!--Barrier[5141:1322592] Task2 0-->
<!--Barrier[5141:1319243] ASync Barrier end 😄-->
<!--Barrier[5141:1319371] Task3 1-->
<!--Barrier[5141:1322592] Task2 1-->
<!--Barrier[5141:1319371] Task3 2-->
<!--Barrier[5141:1322592] Task2 2-->
<!--Barrier[5141:1319371] Task3 3-->
<!--Barrier[5141:1322592] Task2 3-->
<!--Barrier[5141:1319371] Task3 4-->
<!--Barrier[5141:1322592] Task2 4-->
<!--Barrier[5141:1322592] ASync Barrier <NSThread: 0x60c00046dbc0>{number = 5, name = (null)}-->
<!--Barrier[5141:1322592] ASync Barrier <NSThread: 0x60c00046dbc0>{number = 5, name = (null)}-->
<!--Barrier[5141:1322592] ASync Barrier <NSThread: 0x60c00046dbc0>{number = 5, name = (null)}-->
<!--Barrier[5141:1322592] ASync Barrier <NSThread: 0x60c00046dbc0>{number = 5, name = (null)}-->
<!--Barrier[5141:1322592] ASync Barrier <NSThread: 0x60c00046dbc0>{number = 5, name = (null)}-->
<!--Barrier[5141:1322592] Task4 0-->
<!--Barrier[5141:1319371] Task5 0-->
<!--Barrier[5141:1322592] Task4 1-->
<!--Barrier[5141:1319371] Task5 1-->
<!--Barrier[5141:1322592] Task4 2-->
<!--Barrier[5141:1319371] Task5 2-->
<!--Barrier[5141:1322592] Task4 3-->
<!--Barrier[5141:1319371] Task5 3-->
<!--Barrier[5141:1322592] Task4 4-->
<!--Barrier[5141:1319371] Task5 4-->
複製代碼