iOS基礎題

一、category 和 extension 的區別?(分類和擴展的區別)

1,分類有名字,類擴展沒有名字,是一種特殊的分類。

2,分類只能增加方法,增加的屬性僅僅是聲明,并沒有真正的實現,類擴展可以擴展屬性、成員變量和方法。

二、define 和 const 的區別?

1,define 在預處理階段進行替換,const 常量在編譯階段使用。

2,define 不做類型檢查,只是進行替換,const 常量有數據類型,會執行類型檢查。

3,define 不能調試,const 常量可以調試。

4,define 定義的常量在替換后運行過程中會不斷的占用內存,而const 定義的常量儲存在數據段只會copy 一份,節省內存,效率更高。

5,define 可以定義一些簡單的餓函數,const 不可以。

三、block 和 weak 修飾符的區別?

1,_block 不管在 ARC 還是 MRC 模式下都能使用,可以修飾對象也可以修飾基本數據類型。

2,_weak 只能在 ARC 模式下使用,只能修飾對象,不能修飾基本數據類型。

3,_block 修飾的對象可以在block 中重新賦值,_weak 修飾的餓對象不可以。

四、static 關鍵字的作用?

1,static 在函數或者方法中修飾的變量的作用域為當前所在的函數或方法中,這個變量的內存只被分配一次,所以他的值在下一次使用時還是上一次的值。

2,static 在模塊內修飾的全局變量可以被模塊內的所有函數訪問,但不能被模塊外的其他函數訪問。

3,static 在模塊內修飾的函數可以被模塊內的其他函數調用,這個函數的使用范圍被限制在聲明他的模塊內。

4,static 在類中修飾的成員變量屬于整個類所擁有,對類的所有對象只有一份copy。

5,static 在類中修飾的成員函數屬于整個類所擁有,這個函數不接受this 指針,因而只能訪問類的static 成員變量。

五、堆 和 棧 的區別?

1,從管理方式來講:

① 對于棧,是由編譯器自動管理,不需要手動控制。

② 對于堆,釋放工作是由開發者控制,容易產生內存泄漏(memory leak)。

2,從申請的大小方面來講:

① 棧的空間比較小。

② 堆得空間比較大。

3,從數據存儲方面講:

① 棧中存儲的一般都是基本類型,和對象的地址。

② 堆中存儲的一般都是對象本身,block 的 copy 等。

六、Objective-C 使用什么機制管理對象內存?

1,MRC 手動引用計數。

2,ARC 自動引用計數。

3,通過retainCount 的機制來決定對象是否需要釋放。每次runloop 的時候,都會檢查對象的retainCount,如果retainCount 為 0,說明該對象沒有地方需要繼續使用了,就可以釋放了。

七、ARC 通過什么方式幫助開發者管理內存?

1,通過編譯器在編譯的時候,插入類似內存管理的代碼。有個自動釋放池。

八、ARC是為了解決什么問題產生的?

1,ARC,就是automatic reference counting自動引用計數。

2,MRC的缺點:

①在MRC時代當我們要釋放一個堆內存時,首先要確定指向這個堆空間的指針都被release了。

②釋放指針指向的堆空間,首先要確定哪些指針指向同一個堆,這些指針只能釋放一次,MRC下是誰創建,誰釋放,避免重復釋放。

③模塊化操作時,對象可能被多個模塊創建和使用,不能確定最后由誰去釋放。

④多線程操作時,不確定哪個線程最后使用完畢。

九、ARC 模式下還會存在內存泄漏的情況嗎?

1,會,如果有兩個對象循環引用就會造成內存泄漏。

2,Objective-C 的對象與 CoreFoundation 對象進行橋接的時候如果管理不當也會造成內存泄漏。

3,CoreFoundation 中的對象不受 ARC 管理,需要開發者手動釋放。

十、什么情況下使用 weak 關鍵字,相比assign 有什么不同?

1,weak 的使用場景:

① ARC 中在有可能出現循環引用的時候,可以在其中一方使用weak 來引用另一方。比如代理屬性就是使用weak,代理屬性也可以使用assign。

② 自身已經對他進行一次強引用,沒有必要再強引用一次,此時可以使用weak。比如,一個控件作為另一個控件的子控件的時候,因為父控件里的subview 屬性已經是對子控件的一個強引用了,所以在需要聲明為屬性的時候使用weak。

2,weak 和 assign 的不同點:

① weak 策略在屬性所指向的對象被銷毀時,系統會將weak 修飾的屬性對象的指針指向 nil ,在 OC 中給 nil 發消息時不會有問題的(就是訪問 nil ),如果使用 assign 策略在屬性所指的對象銷毀時,屬性對象指針還是指向原來的對象,由于該對象已經被銷毀,這時候就產生了野指針的情況,如果訪問一個野指針,就會導致程序崩潰。

② assign 可以修飾非 OC 對象,而 weak 必須用于 OC 對象。

十一、@property 的本質是什么?

1,@property 其實就是在編譯階段由編譯器自動幫我們生成 ivar 成員變量,getter 方法和 setter 方法。

十二、ivar、getter、setter是如何生成并添加到這個類中的?

1,使用自動合成(autosynthesis)。

2,這個過程由編譯器在編譯階段執行自動合成,所以編譯器里看不到這些合成方法的源代碼。

3,除了生成getter和setter方法外,編譯器還要自動向類中添加成員變量,在屬性名前面添加下劃線,以此作為實例變量的名字。

4,大致生成了五個東西:

①每次增加一個屬性,系統都會在ivar_list中添加一個成員變量的描述。

②在方法列表中(method_list)增加setter和getter方法的描述。

③在屬性列表中(prop_list)增加一個屬性的描述。

④計算該屬性在對象中的偏移量。

⑤然后給出setter和getter方法對應的實現,在setter方法中從偏移量的位置開始賦值,在getter方法中從偏移量位置開始取值,為了能夠讀取正確字節數,系統對象偏移量的指針類型進行了強制類型轉換。

十三、@protocol和category中如何使用@property?(協議和分類中)

1,在protocol中使用property只會生成setter和getter方法的聲明,我們使用屬性的目的,是希望遵守這個協議的對象能夠實現該屬性。

2,category使用@property也是只會生成setter和getter方法聲明,如果我們真的需要給category增加屬性的實現,需要借助runtime的兩個函數:

①objc_setAssociatedObject和

②objc_getAssociatedObject。

十四、@property后面可以有哪些修飾符?

1,原子性natomic特質:

①如果不寫默認就是atomic(系統會自動加上同步鎖,影響性能)。

②在iOS開發中盡量指定為nonatomic,這樣有助于提高程序的性能。

2,讀寫權限,readwrite(可讀可寫)、readonly(只讀)。

3,內存管理語義assign、strong、weak、unsafe_unretained、copy。

4,方法名getter=、setter= .

5,還有不常用的:nonnull、null_resettable、nullable。


十五、使用atomic一定是線程安全的嗎?

1,不是,因為atomic的本意是指屬性的存取方法是線程安全的,并不保證整個對象是線程安全的。

2,舉例:聲明一個NSMutableArray的原子屬性stuff,此時self.stuff和self.stuff = othersulf都是線程安全的。但是,使用[self.stuff objectAtIndex:index]就不是線程安全的,需要用互斥鎖來保證線程安全性。

十六、@synthesize和@dynamic分別有什么作用?

1,@synthesize和@dynamic是@property的兩個對應的詞,如果都沒寫,就默認是@synthesize。

2,@synthesize的語義是如果沒有手動實現setter方法和getter方法,那么編譯器就會自動加上這兩個方法。

3,@dynamic告訴編譯器:屬性的getter和setter方法由用戶自己實現,不會自動生成(readonly只讀的屬性只需提供getter方法即可)。

注意:如果一個屬性被聲明為@dynamic var,然后沒有提供setter和getter方法,編譯的時候沒問題,但是當程序運行到instance.var = someVar,由于缺setter方法,就會導致程序崩潰,或者當程序運行到someVar = instance.var時,由于缺少getter方法同樣會導致崩潰,編譯器沒問題,運行時才執行響應的方法,這就是所謂的動態綁定。


十七、ARC下,不顯示指定任何屬性關鍵字時,默認的關鍵字都有哪些?

1,基本數據的話默認就是:atomic、readwrite、assign。

2,普通的OC對象默認的就是:atomic、readwrite、strong。

十八、@synthesize合成實例變量的規則是什么?假如property名為foo,存在一個名為_foo的實例變量,那么還會自動合成新變量嗎?

1,@synthesize合成成員變量的規則:

①如果指定了成員變量的名稱,會生成一個指定名稱的成員變量。

②如果這個成員變量已經存在了就不在生成了.

③如果指定@synthesize foo ,就會生成一個名為foo的成員變量,也就是說,會生成一個與屬性名相同的成員變量。

④如果是@synthesize foo = _foo,就不會生成成員變涼了。

2,所以,如果指定了成員變量名稱(@synthesize foo),就會生成與屬性同名的成員變量,如果不指定名稱,默認生成的是帶下劃線的成員變量,因為已經存在一個與屬性同名且帶有下劃線的成員變量了,由規則②可得,不會再生成了。


十九、在有了自動合成屬性實例變量之后,@synthesize還有哪些使用場景?

1,首先要搞清楚什么情況下不會自動合成(autosynthesis):

①同時重寫了setter和getter方法時不會自動合成。

②重寫了只讀屬性的getter方法時不會自動合成。

③使用了@dynamic時。

④在@protocol中定義的所有屬性不會自動合成。

⑤在category中定義的所有屬性不會自動合成。

⑥重載的屬性,當在子類中重載了父類中的屬性,必須使用@synthesize來手動合成ivar。

2,應用場景:

①當同時重寫了setter和getter方法時,系統就不會申城ivar。這個時候要么就手動創建,要不就使用@synthesize foo = _foo;關聯@property與ivar.

②可以用來修改成員變量名,建議不這樣做,最好就是使用系統自動生成的。

二十、怎么使用copy關鍵字?

1,NSString、NSArray、NSDictionary等等經常使用copy關鍵字,是因為他們有對應的可變類型NSMutableString、NSMutableArray、NSMutableDictionary。為確保對象中的屬性值不會無意間變動,應該在設置新屬性的時候拷貝一份,保護其封裝性。

2,block也經常使用copy關鍵字:

①block使用copy是從MRC遺留下來的傳統,在MRC中,方法內部的block是在棧區的,使用copy可以把它放到堆區。

②在ARC中可寫可不寫,對于block使用copy還是strong效果都是一樣的,但是建議寫上copy,這樣顯示告知調用者編譯器會自動對block進行了copy操作。

二十一、用@property聲明的NSString、NSArray、NSDictionary為什么經常使用copy關鍵字,如果改用strong,可能造成什么問題?

1,因為使用父類指針可以指向子類對象,使用copy的目的是為了讓本身對象的屬性不受外界影響,使用copy無論傳入的是一個可變的對象還是不可變得對象,本身持有的就是一個不可變的副本。當外界拿到這個屬性進行使用的時候,其實是拷貝了一份,外界修改這個屬性修改的只是copy的那一份,并不會影響這個屬性原來的值。

2,如果我們使用strong,那么這個屬性就有可能指向一個可變的對象,如果這個外部拿到了這個屬性,其實是拿到的一個指向原來屬性值的內存地址指針,如果進行修改,則修改的就是原始值。

二十二、深拷貝和淺拷貝?

1,淺拷貝(shallow copy):對于被復制對象的每一層都是指針賦值。拷貝指針,對象唯一,修改一處則其他處都受影響。

2,深拷貝(one-level-deep copy):在深拷貝操作時,對于被復制對象,至少有一層是深拷貝。深拷貝(拷貝了對象)。修改某一處不一定會影響其他處。

3,完全拷貝(real-deep copy):在完全拷貝操作時,對于被復制對象的每一層都是對象的拷貝。修改一處一定不會影響其他處。

4,非集合類對象的copy與mutableCopy:

{

不可變對象copy:淺拷貝

不可變對象mutableCopy:深拷貝

可變對象copy:深拷貝

可變對象mutableCopy:深拷貝

}

5,集合類對象的copy與mutableCopy:

{

不可變對象copy:淺拷貝

不可變對象mutableCopy:單層深拷貝

可變對象copy:單層深拷貝

可變對象mutableCopy:單層深拷貝

}

6,這里需要注意的是集合對象的內容復制僅限于對象本身,集合對象里的元素仍然是指針拷貝,也就是淺拷貝。

二十三、這個寫法會出現什么問題:@property (copy) NSMutableArray *array;

1,因為copy策略拷貝出來的是一個不可變的對象,使用copy,無論聲明的這個屬性是個可變還是不可變的,在別處拿到這個屬性的時候其實是一個不可變的,把一個真是類型為不可變的對象當做聲明中的可變的來使用,會造成崩潰。

2,這里還有一個問題,該屬性使用了同步鎖,atomic nonatomic都不寫的話默認就是atomic,有同步鎖,會在創建的時候生成一些額外的代碼用于幫助編寫多線程程序,這回帶來性能問題,通過聲明nonatomic可以節省這些不必要的額外開銷,在iOS開發中應該使用nonatomic替代atomic。

二十四、如何讓自定義類可以用copy修飾符?如何重寫帶copy關鍵字的setter?

1,要想讓自己寫的對象具有拷貝動能,則需要實現NSCopying協議,如果自定義的對象分為可變版本與不可變版本,那么就要同時實現NSCopying和NSMutableCopying協議,不過一般沒什么必要,實現NSCopying協議就夠了。

2,//實現不可變版本拷貝

- (id)copyWithZone:(NSZone *)zone;

//實現可變版本拷貝

- (id)mutableCopyWithZone:(NSZone *)zone;

//重寫帶copy關鍵字的setter

- (void)setName:(NSString *)name

{

_name = [name copy];

}

二十五、+(void)load;和+(void)initialize;有什么用?

1,+(void)load;

①當類對象被引入項目時,runtime會向每一個類對象發送load消息。

②load方法會在每一個類甚至分類被引入時僅調用一次,調用的順序,父類>子類>分類。

③由于load方法會在類被import時調用一次,而這個時候往往是改變類的行為的最佳時機,在這里可以使用利用method swizlling來修改原有的方法。

④load方法不會被類自動繼承。

2,+(void)initialize;

①也是在第一次使用這個類的時候調用這個方法,也就是說initialize也是懶加載的。

3,總結:

①在Objective-C中,runtime會自動調用每個類的這兩個方法。

②+load會在類的初始加載時調用。

③+initialize會在第一次調用類的類方法和實例方法之前被調用。

④這兩個方法都是可選的,且只有在實現了他們時才會被調用。

⑤兩者的共同點:兩個方法都是只被調用一次。

二十六、Foundation對象和Core Foundation對象又什么區別?

1,Foundation框架使用OC實現的,Core Foundation是使用C語言實現的。

2,Foundation對象和Core Foundation對象之間的轉換:俗稱橋接

ARC環境下橋接關鍵字:

__bridge //用于Foundation對象和Core Foundation對象之間的轉換

__bridge_retained // Foundation對象轉為Core Foundation對象

__bridge_transfer // Core Foundation對象轉為Foundation對象

3,Foundation對象轉為Core Foundation對象:

①使用__bridge進行橋接,他僅僅是將OC對象的地址傳給了C對象,并沒有轉移對象的所有權,也就是說,使用這個關鍵字進行橋接,如果OC對象釋放了,C對象也就不能用了。在ARC條件下,使用了__bridge來橋接,被轉為OC對象被轉為C對象,那么C對象可以不用主動釋放,因為他們還是同一個地址,ARC會自動管理OC對象,和C對象。

{

NSString *strOC1 = [NSString stringWithFormat:@"abcdefg"];

CFStringRef strC1 = (__bridge CFStringRef)strOC1;

}

②使用__bridge_retained橋接,會將對象的所有權轉給C對象,就算是OC對象釋放了,C對象也能使用。

在ARC條件下,如果使用了這個關鍵字橋接,那么C對象必須自己手動釋放,因為橋接的時候轉移了所有權,C對象不歸ARC管理。

{

NSString *strOC2 = [NSString stringWithFormat:@"abcdefg"];

//CFStringRef strC2 = (__bridge_retained CFStringRef)strOC2;

CFStringRef strC2 = CFBridgingRetain(strOC2); //這一句,就等同于上一句

CFRelease(strC2);

}

4,Core Foundation對象轉Foundation對象:

①使用__bridge橋接,不轉移所有權,C對象釋放了OC對象也就不能用了。

{

CFStringRef strC3 = CFStringCreateWithCString(CFAllocatorGetDefault(), "12345678", kCFStringEncodingASCII);

NSString *strOC3 = (__bridge NSString *)strC3;

CFRelease(strC3);

}

②使用__bridge_transfer橋接,轉移了所有權,C對象釋放了OC對象也能用,會自動釋放C對象,也就是說不用手動釋放C對象了。

{

CFStringRef strC4 = CFStringCreateWithCString(CFAllocatorGetDefault(), "12345678", kCFStringEncodingASCII);

//NSString *strOC = (__bridge_transfer NSString *)strC;

NSString *strOC4 = CFBridgingRelease(strC4); //這一句,就等同于上一句

}

MRC環境下直接強轉:

{

//將Foundation對象轉換為Core Foundation對象,直接強制類型轉換即可

NSString *strOC1 = [NSString stringWithFormat:@"xxxxxx"];

CFStringRef strC1 = (CFStringRef)strOC1;

NSLog(@"%@ %@", strOC1, strC1);

[strOC1 release];

CFRelease(strC1);

//將Core Foundation對象轉換為Foundation對象,直接強制類型轉換即可

CFStringRef strC2 = CFStringCreateWithCString(CFAllocatorGetDefault(), "12345678", kCFStringEncodingASCII);

NSString *strOC2 = (NSString *)strC2;

NSLog(@"%@ %@", strOC2, strC2);

[strOC2 release];

CFRelease(strC2);

}

二十七、addObserver:forKeyPath:options:context:各個參數的作用分別是什么,observer中需要實現哪個方法才能獲得KVO回調?


**

1. self.person:要監聽的對象

2.參數說明

1>觀察者,負責處理監聽事件的對象

2>要監聽的屬性

3>觀察的選項(觀察新、舊值,也可以都觀察)

4>上下文,用于傳遞數據,可以利用上下文區分不同的監聽

*/

//[self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"Person Name"];

/**

*當監控的某個屬性的值改變了就會調用

*

*@param keyPath監聽的屬性名

*@param object屬性所屬的對象

*@param change屬性的修改情況(屬性原來的值、屬性最新的值)

*@param context傳遞的上下文數據,與監聽的時候傳遞的一致,可以利用上下文區分不同的監聽

*//*

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

NSLog(@"%@對象的%@屬性改變了:%@", object, keyPath, change);

}


二十八、KVO的內部實現原理?(蘋果用什么實現的對一個對象的KVO鍵值監聽)

1,KVO是基于runtime機制實現的。

2,當某個類的屬性對象第一次被觀察時,系統就會在運行時動態的創建一個該類的派生類,在這個派生類中重寫基類中任何被觀察屬性的setter方法,派生類在被重寫的setter方法內部實現真正的通知機制。

3,如果原來的類為Person,那么生成的派生類名為NSKVONotifying_Person(在原類類名的基礎前加NSKVONotifying_)。

4,每個類的對象都有一個isa指針指向當前的類,當一個類的對象第一次被觀察,那么系統就會將isa指針指向動態生成的這個派生類,在給被監控的屬性賦值時執行的其實是派生出來的這個類的setter方法。

5,鍵值觀察通知依賴于NSObject的兩個方法:willChangeValueForKey;和didChangeValueForKey;在一個被觀察屬性發生改變之前,will方法一定會被調用,這一次記錄舊值,當發生改變之后did方法又會被調用,這一次記錄新值,繼而調用observeValueForKey:ofObject:change:context:

6,補充:KVO的這套實現機制中蘋果偷偷重寫了class方法,讓我們誤認為還是使用的當前類,從而隱藏派生類。

二十九、如何手動觸發一個value的KVO?

1,自動觸發場景:在注冊KVO之前設置一個初始值,注冊之后設置一個不一樣的值,值變化了就觸發了。

2,手動觸發:


@property (nonatomic, strong) NSDate *now;

- (void)viewDidLoad

{

[super viewDidLoad];

// “手動觸發self.now的KVO”,必寫。

[self willChangeValueForKey:@"now"];

// “手動觸發self.now的KVO”,必寫。

[self didChangeValueForKey:@"now"];

}


三十、KVC中,有個實例變量NSString *_foo ,調用setValue:forKey:時是以foo還是_foo作為key?

1,都可以。

三十一、KVC的keyPath中的集合運算符如何使用?

1,必須用在集合對象上或普通對象的集合屬性上。

2,簡單集合運算符有@avg , @count, @max ,@min , @sum.

3,格式@"@sum.age"或@"集合屬性.@max.age"

三十二、KVC和KVO的keyPath一定是屬性嗎?

1,可以是成員變量。

三十三、如何關閉KVO的默認實現,并進入自定義的KVO實現?

具體內容連接自自定義KVO 的實現---原文來自顧鵬

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,707評論 2 370

推薦閱讀更多精彩內容