applem2源碼
㈠ php怎麼抓取這個鏈接https://locate.apple.com/cn/zh/service/pt=3&lat=23.134521&lon=113.358803的源碼
<?php
function dg_string($data,$flagA, $flagB, $start = 0){//配套截取字元串
$flagAL=strlen($flagA);
$flagBL=strlen($flagB);
$rn='';
$a=$b=0;
if(($findA=strpos($data,$flagA, $start))!==false){
$a=1;
$tmpA=$findA;
$findB=$findA+$flagAL;
$findA=$findB;
while($a!=$b){
if(($findB = strpos($data, $flagB, $findB))!==false){
$b++;
if(($findA = strpos($data, $flagA, $findA))!==false){
if($findA>$findB){
if($a==$b){
//結束
$findB+=$flagBL;
$rn=substr($data,$tmpA,$findB-$tmpA);
} else {
$a++;
$findB=$findA+$flagAL;
$findA=$findB;
}
} else {
$a++;
$findA+=$flagAL;
$findB+=$flagBL;
}
} else {
if($a==$b){
//結束
$findB+=$flagBL;
$rn=substr($data,$tmpA,$findB-$tmpA);
} else {
//標記不完整
$findB+=$flagBL;
}
}
} else {
//標記不完整
$rn=substr($data,$tmpA);
$rn.=str_repeat($flagB,$a-$b);
break;
}
}
}
return $rn;
}
$html = file_get_contents('https://locate.apple.com/cn/zh/service/?pt=3&lat=23.134521&lon=113.358803');//獲取源碼
$find = strpos($html, 'window.resourceLocator.setup');
$json1 = dg_string($html, '{', '}', $find);//獲取第一個JSON數據
$find = strpos($html, 'window.resourceLocator.storeSetup');
$json2 = dg_string($html, '{', '}', $find);//獲取第二個JSON數據
$arr1 = json_decode($json1, true);//第一個JSON數據轉為數組
$arr2 = json_decode($json2, true);//第二個JSON數據轉為數組
print_r($arr1);
print_r($arr2);
//得到了數組,你想獲取哪個參數都行了,你自己看著辦吧,樓主可親測代碼
?>
㈡ Apple 源碼用到的一些數據結構
本篇英文名叫 CWC:Kitchen Tools That Cook Loves ,翻譯過來的意思是 蘋果源碼中出現的一些數據結構 ,不斷積累更新。
CWC : Cooking With Cook ,翻譯過來的中文意思就是 作為一個長期熱愛蘋果的蘋果開發者,我們要陪著水果公司一起積累和成長。
目前: entsize_list_tt 、 list_array_tt 、 cache_t's buckets ...
entsize_list_tt 其實就是一個通用的容器,可以獲取 內部的迭代器,用於遍歷內部存儲的元素
出現場景:
三者的聲明頭如下:
entsize_list_t 定義源碼,省略大部分方法:
這個類用來表示一個空、單數組、或者多數組。它和 list 的帆桐區別就是 多了一個多維數組的封裝。
出現場景:
ro 中沒有,只有三個單 List。
三者的聲明頭如下:
list_array_tt 源碼部分如下:
cache_t 的結構體定義:
buckets 的內部是一個連續的存儲空間,存儲是一個散列表。
開辟聲明的函數調用的是 calloc
當 msgSend 的時候,就會調用 fillCache 進行方法的緩存,存儲的涉及 cls sel 和 imp
bucket_t 的結構體很有意思,arm64 和 i386 的兩個值的順序是反著的。
arm64 的時候是 :
armv7* , i386 和 x86_64 的時候是:
源碼注釋:
初始的 capacity 是 4。
源碼中 cache_t::insert(cls, sel, imp, reveiver) 方法調用的時候,判斷擴容。
fastpath(newOccupied + CACHE_END_MARKER <= capacity / 4 * 3)
也就是說當大於四分之三的時候,就會進行擴容操作,每次 double 擴容
capacity = capacity ? capacity * 2 : INIT_CACHE_SIZE;
當然不是無限制的擴容,有一個最大容量的限制:
MAX_CACHE_SIZE = 1 << 16
這個類型應該是執行最多次的,看一些文章說一秒鍾iOS中執行幾百萬次
explicit_atomic用來給catchT緩存方法用,核心是原子性和線程安全。
weak弱引用的散列表
擴展: non-fragile structs 是什麼?OC 1.0 (iOS自始至終都是2.0起的,Mac最開始是1.0)桐轎缺譯器生成了一個 ivar 布局,顯示了在類中從哪可局辯以訪問 ivars ,對 ivar 的訪問就可以通過 對象地址 + ivar偏移位元組 的方法。蘋果更新了NSObject類,例如增加一些屬性,這個又是靜態庫,發布新版本的系統,這個時候布局就出錯了,就不得不重新編譯子類來恢復兼容性。(那如果是在線上運行的app,升級系統後就沒辦法運行了)
使用 Non Fragile ivars 時,程序進行檢測來調整類中新增的 ivar 的偏移量。 這樣就可以通過 對象地址 + 基類大小 + ivar偏移位元組 的方法來計算出 ivar 相應的地址,並訪問到相應的 ivar。(即使升級iOS系統,之前的app也能正常運行)
擴展再擴展: 為什麼OC類不能動態添加成員變數? runtime函數中,確實有一個class_addIvar()函數用於給類添加成員變數,但是文檔中特別說明: This function may only be called after objc_allocateClassPair and before objc_registerClassPair. Adding an instance variable to an existing class is not supported. 這個函數只能在「構建一個類的過程中」調用。一旦完成類定義,就不能再添加成員變數了。經過編譯的類在程序啟動後就被runtime載入,沒有機會調用addIvar。程序在運行時動態構建的類需要在調用objc_registerClassPair之後才可以被使用,同樣沒有機會再添加成員變數。
理論上說,我還是認為可以添加,只是為什麼一定不可以,就不得而知了。