JSPatch 學(xué)習(xí)二 -- 基礎(chǔ)用法(3)

8. GCD

使用 dispatch_after() 麻车;dispatch_async_main() ;dispatch_sync_main() 受裹;dispatch_async_global_queue() 接口調(diào)用GCD方法:

// Obj-C

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{// do something});

dispatch_async(dispatch_get_main_queue(), ^{// do something});

// JS

dispatch_after(1.0, function(){// do something})

dispatch_async_main(function(){// do something})

dispatch_sync_main(function(){// do something})

dispatch_async_global_queue(function(){// do something})

9. 傳遞 id* 參數(shù)

如果你需要傳遞 id* 參數(shù)碌补,像 NSURLConnection 里的這個接口里的 NSError **:

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;

這里傳入的是一個指向 NSObject 對象的指針,在方法里可以修改這個指針指向的對象棉饶,調(diào)用后外部可以拿到新指向的對象厦章,對于這樣的參數(shù),首先需要引入 JPMemory 擴展照藻,然后按以下步驟進行傳遞和獲韧嗫小:

使用 malloc(sizeof(id)) 創(chuàng)建一個指針

把指針作為參數(shù)傳給方法

方法調(diào)用完,使用 pval() 拿到指針新指向的對象

使用完后調(diào)用 releaseTmpObj() 釋放這個對象

使用 free() 釋放指針

舉個例子:

//OC

- (void)testPointer:(NSError **)error {

NSError *err = [[NSError alloc]initWithDomain:@"com.jspatch" code:42 userInfo:nil];

*error = err;

}

//JS

//malloc() pval() free() is provided by JPMemory extension

require('JPEngine').addExtensions(['JPMemory'])

var pError = malloc(sizeof("id"))

self.testPointer(pError)

var error = pval(pError)

if (!error) {

console.log("success")

} else {

console.log(error)

}

releaseTmpObj(pError)

free(pError)

若反過來你想在 JS 替換上述 -testPointer: 方法幸缕,構(gòu)建 NSError 對象賦給傳進來的指針群发,可以這樣寫:

defineClass('JPClassName', {

testPointer: function(error){

var? tmp = require('NSError').errorWithDomain_code_userInfo("test", 1, null);

var newErrorPointer = getPointer(tmp)

memcpy(error, newErrorPointer, sizeof('id'))

}

);

10. 常量晰韵、枚舉、宏熟妓、全局變量

常量/枚舉

Objective-C 里的常量/枚舉不能直接在 JS 上使用雪猪,可以直接在 JS 上用具體值代替:

//OC

[btn addTarget:self action:@selector(handleBtn) forControlEvents:UIControlEventTouchUpInside];

//UIControlEventTouchUpInside的值是1<<6

btn.addTarget_action_forControlEvents(self, "handleBtn", 1<<6);

或者在 JS 上重新定義同名的全局變量:

//js

var UIControlEventTouchUpInside? = 1 << 6;

btn.addTarget_action_forControlEvents(self, "handleBtn", UIControlEventTouchUpInside);

有些常量字符串,需要在 OC 用 NSLog 打出看看它的值是什么:

//OC

[[NSAttributedString alloc].initWithString:@"str" attributes:@{NSForegroundColorAttributeName: [UIColor redColor]];

上面代碼中 NSForegroundColorAttributeName 是一個靜態(tài)字符串常量起愈,源碼里看不出它的值只恨,可以先用 NSLog 打出它的值再直接寫在 JS 上:

//OC

NSLog(@"%@", NSForegroundColorAttributeName) //output 'NSColor'

NSAttributedString.alloc().initWithString_attributes("無效啊", {'NSColor': UIColor.redColor()});

獲取宏值

Objective-C 里的宏同樣不能直接在 JS 上使用。若定義的宏是一個值告材,可以在 JS 定義同樣的全局變量代替坤次,若定義的宏是程序,可以在JS展開宏:

#define TABBAR_HEIGHT 40

#define SCREEN_WIDTH [[UIScreen mainScreen] bounds].size.height

[view setWidth:SCREEN_WIDTH height:TABBAR_HEIGHT];

//JS

view.setWidth_height(UIScreen.mainScreen().bounds().height, 40);

若宏的值是某些在底層才能獲取到的值斥赋,例如 CGFLOAT_MIN,可以通過在某個類或?qū)嵗椒ɡ飳⑺祷夭蛘哂锰砑訑U展的方式提供支持:

@implementation JPMacroSupport

+ (void)main:(JSContext *)context

{

context[@"CGFLOAT_MIN"] = ^CGFloat() {

return CGFLOAT_MIN;

}

}

@end

require('JPEngine').addExtensions(['JPMacroSupport'])

var floatMin = CGFLOAT_MIN();

修改宏值

JSPatch 不支持修改宏的值疤剑,若要修改,需要替換所有使用到這個宏的方法闷堡。例如:

#define VIEW_HEIGHT 40

@implementation JPMethodDemo

+ (void)func

{

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, VIEW_HEIGHT)];

...

}

@end

//JS

var VIEW_HEIGHT_NEW = 20;

defineClass('JPMethodDemo', {

func: function() {

var view = UIView.alloc().initWithFrame({x:0, y:0, width:100, height:VIEW_HEIGHT_NEW});

...

}

});

全局變量

在類里定義的 static 全局變量無法在 JS 上獲取到隘膘,若要在 JS 拿到這個變量,需要在 OC 有類方法或?qū)嵗椒ò阉祷兀?/p>

static NSString *name;

@implementation JPTestObject

+ (NSString *)name {

return name;

}

@end

var name = JPTestObject.name() //拿到全局變量值

11. Swift

使用 defineClass() 覆蓋 Swift 類時杠览,類名應(yīng)為 項目名.原類名弯菊,例如項目 demo 里用 Swift 定義了 ViewController 類,在 JS 覆蓋這個類方法時要這樣寫:

defineClass('demo.ViewController', {})

對于調(diào)用已在 swift 定義好的類踱阿,也是一樣:

require('demo.ViewController')

需要注意幾點:

只支持調(diào)用繼承自 NSObject 的 Swift 類

繼承自 NSObject 的 Swift 類管钳,其繼承自父類的方法和屬性可以在 JS 調(diào)用,其他自定義方法和屬性同樣需要加 dynamic 關(guān)鍵字才行软舌。

若方法的參數(shù)/屬性類型為 Swift 特有(如 Character / Tuple)才漆,則此方法和屬性無法通過 JS 調(diào)用。

Swift 項目在 JSPatch 新增類與 OC 無異佛点,可以正常使用醇滥。

詳見這篇文章

12. 加載動態(tài)庫

對于 iOS 內(nèi)置的動態(tài)庫,若原 APP 里沒有加載超营,可以通過以下方式動態(tài)加載鸳玩,以加載 SafariServices.framework 為例:

var bundle = NSBundle.bundleWithPath("/System/Library/Frameworks/SafariServices.framework");

bundle.load();

加載后就可以使用 SafariServices.framework 了。

13. 調(diào)試

可以使用 console.log() 打印一個對象演闭,作用相當(dāng)于 NSLog()不跟,會直接在 XCode 控制臺打出。

console.log() 支持任意參數(shù)船响,但不支持像 NSLog 這樣 NSLog(@"num:%f", 1.0) 的拼接:

var view = UIView.alloc().init();

var str = "test";

var num = 1;

console.log(view, str, num)

console.log(str + num);? //直接在JS拼接字符串

也可以通過 Safari 的調(diào)試工具對 JS 進行斷點調(diào)試

學(xué)自https://github.com/bang590/JSPatch/wiki/JSPatch-基礎(chǔ)用法#super

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末躬拢,一起剝皮案震驚了整個濱河市躲履,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌聊闯,老刑警劉巖工猜,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異菱蔬,居然都是意外死亡篷帅,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門拴泌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來魏身,“玉大人,你說我怎么就攤上這事蚪腐〖牵” “怎么了?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵回季,是天一觀的道長家制。 經(jīng)常有香客問我,道長泡一,這世上最難降的妖魔是什么颤殴? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮鼻忠,結(jié)果婚禮上涵但,老公的妹妹穿的比我還像新娘。我一直安慰自己帖蔓,他們只是感情好矮瘟,可當(dāng)我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著讨阻,像睡著了一般芥永。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上钝吮,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天埋涧,我揣著相機與錄音,去河邊找鬼奇瘦。 笑死棘催,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的耳标。 我是一名探鬼主播醇坝,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了呼猪?” 一聲冷哼從身側(cè)響起画畅,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宋距,沒想到半個月后轴踱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡谚赎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年淫僻,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片壶唤。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡雳灵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出闸盔,到底是詐尸還是另有隱情悯辙,我是刑警寧澤,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布迎吵,位于F島的核電站笑撞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏钓觉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一坚踩、第九天 我趴在偏房一處隱蔽的房頂上張望荡灾。 院中可真熱鬧,春花似錦瞬铸、人聲如沸批幌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽荧缘。三九已至,卻和暖如春拦宣,著一層夾襖步出監(jiān)牢的瞬間截粗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工鸵隧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留绸罗,地道東北人。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓豆瘫,卻偏偏與公主長得像珊蟀,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子外驱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,455評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1. require 在使用Objective-C類之前需要調(diào)用require('className’): req...
    深藏不露的zack閱讀 1,372評論 0 0
  • 做iOS開發(fā)的朋友都知道,蘋果上傳Appstore審核周期比較長,這樣App一旦出現(xiàn)Bug就不能急時修復(fù),這也許是...
    MangoJ閱讀 550評論 0 2
  • 第一次聽到這首歌的時候在KTV,它已經(jīng)火的一塌糊涂感覺民謠里,以地名為歌名的不在少數(shù)可能瘫里,離開家的時間長了終免不了...
    rollingstarky閱讀 239評論 0 0
  • 我最親愛的寶貝兒: 感謝上天把你賜給了我梦湘,我的生活也因你豐滿而充實,媽媽每天看著你成長心里有說不出的開心。再過幾個...
    木棉飄香閱讀 668評論 4 6
  • 我嗅到了森林里薄霧未散的清冽氣息典徊,見到了濃密樹蔭和熹微晨光的交雜,聽到了滾落花瓣的露珠和報晨的鳥語——也感到了你撒...
    公子卿言閱讀 173評論 0 0