iOS 開發(fā)總結(jié)(一直更新)

1费封、我能從我的程序員生涯中學到什么?

答:別人一想到程序員蒋伦,腦海中浮想的除了工資高弓摘,應(yīng)該是思維嚴謹,邏輯能力強痕届,是的韧献,寫程序能讓人培養(yǎng)成思維嚴謹?shù)牧晳T末患;但如果我寫的程序的問題沒有越來越少,那顯然是非常失敗的锤窑,即使你能實現(xiàn)很多炫酷的功能璧针,但只要多出現(xiàn)幾個BUG,別人也會認為你是不個不折不扣的菜逼,以前有點不服氣渊啰,但現(xiàn)在我自己也非常認同,寫程序一定要盡量考慮周全探橱,培養(yǎng)自己嚴謹?shù)乃季S習慣,培養(yǎng)跨領(lǐng)域的能力才是最重要的

2绘证、我可能從我的程序員生涯中得到什么壞處隧膏?

答: 頸椎病,一敲代碼就入神嚷那,連續(xù)幾個小時都不離開座位胞枕; 缺乏運動和久坐帶來的一些綜合癥狀; 不是要自己有多在意這些魏宽,但如果一點都不在意腐泻,一定會付出代價的, 平時有空就多去運動一下队询,每天認真做一遍頸椎操派桩,保護好自己的頸椎,腰椎也要留心一下娘摔;


3窄坦、對于項目中的第三庫一定要進行再次封裝,包括網(wǎng)絡(luò)凳寺、刷新鸭津、提示、模型轉(zhuǎn)換等所有能封裝的部分肠缨,一直用MJExtension來做字典轉(zhuǎn)模型逆趋,突然想用YYModel了,項目中替換很麻煩晒奕,刷新也一樣闻书,一直用第三方框架,突然想自己寫脑慧,改起來麻煩的不要不要的;


4魄眉、熟悉一下測試的幾種方案,例如交叉測試(一個功能正在運行闷袒,另一個功能運行對它的影響坑律,例如 掃碼時打開燈光,突然退到后臺囊骤,再回來查看晃择,可能燈光已經(jīng)熄滅冀值,按鈕還沒改變狀態(tài))等,這樣寫程序時才知道往哪些方面考慮


5宫屠、多寫點代碼塊列疗,寫起代碼來會很快,我把自定義Cell都封裝了代碼塊浪蹂,用xib布局cell就沒有純手寫這么快了,改起來還麻煩抵栈,這就是代碼塊的好處;


6乌逐、主控制器因為代碼比較多竭讳,結(jié)構(gòu)一定要清晰,才方便尋找浙踢,插入的類按 服務(wù)工具類+MVC 劃分绢慢,屬性按修飾符劃分,下面代碼按功能劃分洛波,如下
#import "ViewController.h"

// 工具和服務(wù)類
#import "Header.h"
#import "Tool1.h"
#import "Tool2.h"

// Model
#import "Model1.h"
#import "Model2.h"
#import "Model3.h"

// View
#import "View1.h"
#import "View2.h"
#import "View3.h"

// Controller
#import "ViewController1.h"
#import "ViewController2.h"
#import "ViewController3.h"

@interface ViewController ()

// 按修飾符劃分
@property (nonatomic, assign) NSInteger num1;
@property (nonatomic, assign) NSInteger num2;

@property (nonatomic, strong, nonnull) NSMutableArray<NSString *> *object3;
@property (nonatomic, strong, nonnull) NSMutableArray<NSNumber *> *object4;

@property (nonatomic, copy, nullable) NSString *object5;
@property (nonatomic, copy, nullable) NSString *object6;

@property (nonatomic, weak) UILabel *object1;
@property (nonatomic, weak) UILabel *object2;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

#pragma mark - 初始化View
- (void)initView
{
    
}

#pragma mark - 系統(tǒng)方法胰舆,界面顯示到銷毀

#pragma mark - 代理

#pragma mark - 按鈕點擊,通知蹬挤,定時器

#pragma mark - 輔助方法

#pragma mark - 懶加載


@end


7缚窿、定時器不是馬上開始的,多久觸發(fā)一次事件焰扳,多久才開始,記得在退出頁面的時候釋放定時器倦零,否則控制器不會釋放;
8吨悍、如果錯誤提示中出現(xiàn)了duplicate這樣的字眼扫茅,很可能就是引入了.m文件
9、UIView的tag不能為0育瓜;
10葫隙、字典轉(zhuǎn)JSON字符串;
NSData *data = [NSJSONSerialization dataWithJSONObject:params 
options:NSJSONWritingPrettyPrinted error:nil];
NSString *paramStr = [[NSString alloc] initWithData:data 
encoding:NSUTF8StringEncoding];


11躏仇、有時在動畫過程中恋脚,需要避免用戶重復(fù)操作,否則很容易崩潰焰手,設(shè)置[[UIApplication sharedApplication] beginIgnoringInteractionEvents]; 允許用戶操作[[UIApplication sharedApplication] endIgnoringInteractionEvents]糟描;


12、如果延時執(zhí)行事件會被多次觸發(fā)书妻,那是一件很危險的事情船响,需要取消前面的延時執(zhí)行事件
[self performSelector:<#(nonnull SEL)#> 
withObject:<#(nullable id)#> afterDelay:<#(NSTimeInterval)#>]; // 延時執(zhí)行

[NSObject cancelPreviousPerformRequestsWithTarget:<#(nonnull id)#> 
selector:<#(nonnull SEL)#> object:<#(nullable id)#>]  // 取消延時執(zhí)行


13、測試某部分代碼的運行時間,
NSTimeInterval beginTime = CFAbsoluteTimeGetCurrent();
...... // 執(zhí)行代碼
NSTimeInterval endTime = CFAbsoluteTimeGetCurrent();
time = endTime - beginTime; // 運行時間


14灿意、對某個控件截圖
UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();


15、添加毛玻璃效果
UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:effect];
effectView.contentView = 控件;


16崇呵、添加長按手勢缤剧,在手勢開始時才執(zhí)行方法,避免方法被調(diào)用兩次
- (void)longPress:(UILongPressGestureRecognizer *)longPressGesture
{
     if (UIGestureRecognizerStateBegan != longPressGesture.state) {
         return;
     }

     ... // 執(zhí)行方法
}


17域慷、輸入框有值時才能點擊return key;
textField.enablesReturnKeyAutomatically = YES;


18荒辕、isKindOfClass 判斷對象是否是一個類的成員,或者是派生自該類的成員 isMemberOfClass 確定對象是否是當前類的成員;


19犹褒、tableView設(shè)置cell的分割線從屏幕左側(cè)邊緣開始
** cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0);


20抵窒、tableView當內(nèi)容不夠時,去掉底部的分割線
self.tableView.tableFooterView = [[UIView alloc] init];


21叠骑、UITableView設(shè)置為Plain的樣式時李皇,你又有多組時,組頭就會默認有懸浮效果宙枷,停留在上邊掉房,如果不想組頭懸浮在上邊,可以將樣式設(shè)為Grouped,把足部設(shè)置很小慰丛,解決這問題卓囚;
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(x, y, w, h)
style:UITableViewStyleGrouped];
tableView.sectionFooterHeight = 0.0001;


22、設(shè)置UITableViewCell之間的間距,在自定義cell中重寫setFrame方法
- (void)setFrame:(CGRect)frame
{
    frame.origin.y += 5;
    frame.size.height -= 5;

    [super setFrame:frame];
}


23诅病、修改UISearchController上searchBar的風格哪亿,遍歷子控件(很有用),找到合適的, 設(shè)置想要的子控件的顏色和分格贤笆;
UIImageView *barImageView = self.searchController.searchBar.subviews[0].subviews[0];
barImageView.layer.borderColor = [UIColor lightGrayColor];
barImageView.layer.borderWidth = 1;

UIView *textView = self.searchController.searchBar.subviews[0].subviews[1];
textView.backgroundColor = [UIColor whiteColor];


24蝇棉、監(jiān)測WKWebView的加載進度
[wkWebView addObserver:self forKeyPath:@"estimatedProgress" 
options:NSKeyValueObservingOptionNew context:nil];


25、一個控件獲取在某個控件上的坐標點的四種方式
// 獲取View在window上的坐標點的四種寫法
 // 使用 convertRect:toRect 方法
CGRect rect = [view  convertRect:view.bounds toRect:window]; 
CGRect rect = [view.superView  convertRect:view.frame toRect:window];

 // 使用 convertRect:from 方法
CGRect rect = [window  convertRect:view.bounds from:view]; 
CGRect rect = [window  convertRect:view.frame from:view.superView];


26苏潜、iOS11獲取最上面的window
// iOS 11 以前
UIView *windowView = [[UIApplication sharedApplication].windows lastObject]; 
// iOS 11 以后
UIView *windowView = [[UIApplication sharedApplication].windows firstObject]; 


27银萍、某個控件有雙擊和單擊時,設(shè)置雙擊失敗時恤左,才觸發(fā)單擊
[oneTap requireGestureRecognizerToFail:doubleTap];


28贴唇、設(shè)置圖片捏合縮放,雙擊放大
// 首先把imageView添加到scrollview中

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return self.imageView;  // 在代理返回當前imageView現(xiàn)
}

- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
    // 保證繞著中心點縮放飞袋,
    CGSize boundsSize = self.scrollView.bounds.size;
    CGRect frameToCenter = self.imageView.frame;
    if (frameToCenter.size.width < boundsSize.width) {
       frameToCenter.origin.x = floorf((boundsSize.width -
           frameToCenter.size.width) * 0.5f);
    } else {
       frameToCenter.origin.x = 0;
    }
    if (frameToCenter.size.height < boundsSize.height) {
       frameToCenter.origin.y = floorf((boundsSize.height - frameToCenter.size.height) * 0.5f);
    } else {
       frameToCenter.origin.y = 0;
    }
    if (!CGRectEqualToRect(self.imageView.frame, frameToCenter)) {
       self.imageView.frame = frameToCenter;
    }
}

-(void)doubleTap:(UITapGestureRecognizer *)tapBgRecognizer
{
    CGFloat scale = 4; // 最大縮放比例
    if (self.self.imageView.frame.frame.size.width < kScreenWidth * scale) {
        CGPoint point = [tapBgRecognizer locationInView:self.imageView.frame];
        CGFloat xSize = kScreenWidth / scale;
        CGFloat ySize = kScreenHeight / scale;
        CGRect zoomRect = CGRectMake(point.x - xSize * 0.5f,
           point.y - ySize * 0.5f, xSize, ySize);
        self.scrollView.maximumZoomScale = scale;
           // 以點擊點為中心縮放到最大
        [self.scrollView zoomToRect:zoomRect animated:YES];
    } else {
        [UIView animateWithDuration:0.25 animations:^{
        self.scrollView.zoomScale = 1.0;
        self.scrollView.contentSize = self.scrollView.bounds.size;
        self.self.imageView.frame.frame = self.originFrame;
        }];
    }
}


29戳气、尋找當前控件的控制器
- (UIViewController *)ht_viewController{
    for (UIView* next = self; next; next = next.superview) {
        UIResponder* nextResponder = [next nextResponder];
        if ([nextResponder isKindOfClass:[UIViewController class]]) {
            return (UIViewController*)nextResponder;
        }
    }
    return nil;
}


30、UITextField的inputView屬性是指第一響應(yīng)的不是鍵盤巧鸭,而是賦值給inputView的那個view瓶您, inputAccessoryView 是指往鍵盤上添加另一個view;


31、設(shè)置鍵盤在UIScrollView拖動動時消失
scrollview.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag


32、設(shè)置UITableViewCell之間的分割線顏色呀袱;
self.tableView.separatorColor = [UIColor redColor];


33贸毕、iOS9以后點擊狀態(tài)欄,UIScrollView可返回頂部;


34夜赵、顯示狀態(tài)欄的網(wǎng)絡(luò)請求菊花明棍;
 // 顯示菊花, NO為關(guān)閉菊花
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;


35寇僧、讓UILabel的字體適應(yīng)指定的寬度摊腋,當寬度大時,字體不變嘁傀, 寬度小時兴蒸, 字體變小適應(yīng)寬度
label.adjustsFontSizeToFitWidth = YES;


36、監(jiān)聽拖動進度條時的狀態(tài)
// 監(jiān)聽進度條的拖動
[slider addTarget:self action:@selector(sliderChange:event:) 
forControlEvents:UIControlEventValueChanged];

- (void)sliderChange:(UISlider *)slider event:(UIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];
    // 根據(jù)狀態(tài)來做相應(yīng)的事情细办,避免拖動時一直調(diào)用某些事件
    switch (touch.phase) {
    case UITouchPhaseBegan:    // 開始
    case UITouchPhaseMoved:    // 拖動
    case UITouchPhaseEnded:    // 結(jié)束
    default:
        break;
    }
}


37橙凳、讓UITableView的某一行滾到底部;
 [self.tableView scrollToRowAtIndexPath:indexPath 
    atScrollPosition:UITableViewScrollPositionBottom animated:YES];


38笑撞、以Modal的形式push出一個界面痕惋;
[UIView  beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[self.navigationController pushViewController:vc animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight 
   forView:self.navigationController.view cache:NO];
[UIView commitAnimations];


39、阻止設(shè)備自動鎖屏 [UIApplication sharedApplication].idleTimerDisabled = YES; 在后臺不管用娃殖,退出當前頁面時值戳,記得設(shè)為NO


40、為了避免循環(huán)引用炉爆,在block中我們一般都用弱引用堕虹,但是block中的弱引用對象可能會提前釋放,造成崩潰芬首,我們需要在block中強引用一下這個弱對象赴捞;
__weak __typeof(self)weakSelf = self;
view.callback = ^(ViewStatus status) {
   // 強引用這個對象,避免執(zhí)行到一半 self釋放郁稍,造成崩潰赦政;
   __strong __typeof(weakSelf)strongSelf = weakSelf;
   [strongSelf doSomething];
}


41、如果一個參數(shù)中需要包含多個枚舉值耀怜,用NS_OPTIONS恢着,不要用NS_ENUM
// 位運算保證任意組合的枚舉值進行或運算能得到唯一的值
typedef NS_OPTIONS(NSUInteger, TestName) {
    TestNameXiaoHua = 1 << 0,    // 小花
    TestNameXiaoBai = 1 << 1,    // 小白
    TestNameXiaoHei = 1 << 2     // 小黑
};
[self eat:TestNameXiaoHua | TestNameXiaoBai]; // 讓小花和小白有飯吃;

- (void)eat:(TestName)name
{
    if ((name & TestNameXiaoHua) || (name & TestNameXiaoBai)) {
       NSLog(@"有飯吃");
   }
}


42财破、快速生成一個帶值的可變字典
NSMutableDictionary *mutDic = @{@"key": @"value"}.mutableCopy;


43掰派、忽略編譯器警告
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"  // 設(shè)置要忽略的類型 這里是GNU警告
// 代碼
#pragma clang diagnostic pop


44、為了避免多線程訪問數(shù)據(jù)庫左痢,造成數(shù)據(jù)混亂靡羡,讓讀寫方法都在同一個隊列中進行系洛;
static const void * const IOKey = &IOKey;

// 開辟一個單例隊列
dispatch_queue_t NTESDispatchIOQueue()
{
    static dispatch_queue_t queue;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    //  dispatch_queue_create("", DISPATCH_QUEUE_SERIAL)
    queue = dispatch_queue_create("io.queue", 0);
    dispatch_queue_set_specific(queue, IOKey, (void *)IOKey, NULL); // 設(shè)置隊列的的標記
    });
    return queue;
}

typedef void(^dispatch_block)(void);
void io_sync_safe(dispatch_block block)
{
    // 如果是自己設(shè)置的隊列,執(zhí)行block
    if (dispatch_get_specific(IOKey))
    {
       block();
    }
    else  // 如果不是自己設(shè)置的隊列略步,先創(chuàng)建隊列描扯,再執(zhí)行block
    {
        dispatch_sync(NTESDispatchIOQueue(), ^() {
        block();
    });
}


45、監(jiān)聽UITextField值的改變趟薄,請使用 下面這個方法
[_textViewaddTarget:self.action:@selector(textFieldDidChangeValue:)
forControlEvents:UIControlEventEditingChanged]

不要去使用下面這個代理方法荆烈,這個方法可能會監(jiān)聽不到

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:
(NSRange)range replacementString:(NSString *)string {
 },


46竟趾、把C++算法庫封裝在OC文件里形成靜態(tài)庫時,記得把OC的.m文件改成.mm文件


47宫峦、如果視圖里面存在唯一一個UIScrollView或其子類View時岔帽,會主動設(shè)置相應(yīng)的內(nèi)邊距,避免被導航欄遮住导绷,如果我們的導航欄不透明犀勒,原點會從我們的導航欄下方算起,導致上方留白妥曲,解決這問題:
if (@available(iOS 11.0, *)) {
   self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;//UIScrollView也適用
}else {
   self.automaticallyAdjustsScrollViewInsets = NO;
}


48贾费、如果數(shù)組中的元素是唯一的,或者要查詢某個數(shù)據(jù)是否在該數(shù)組中檐盟,不要使用NSArray, 而是使用集合NSSet,集合采用的是哈希表褂萧,查詢速度更快;


49葵萎、動畫里的萬能神器CAShapeLayer,性能特別好导犹,能實現(xiàn)很多神奇的效果,做什么動畫前優(yōu)先考慮它羡忘,尤其做股票財經(jīng)谎痢、健康A(chǔ)PP類的,經(jīng)常需要畫圖卷雕,如果遇到性能問題节猿,試試它;


50漫雕、swift中為了避免循環(huán)引用滨嘱,我們使用weak或者unowned來解決,但它們是有區(qū)別的浸间; unowned更像OC里的unsafe_unretained九孩,當引用對象釋放了以后,它仍然會保持對引用對象的一個無效引用发框,如果嘗試調(diào)用方法和成員屬性的話躺彬,程序就會崩潰煤墙; weak則會在引用的內(nèi)容被釋放后,它會自動地變成 nil宪拥; 因此我們在使用它時仿野,如果你引用對象不會釋放, 使用unowned她君,寫起來方便點脚作; 如果你引用對象會被釋放,請使用weak,例如網(wǎng)絡(luò)請求缔刹;


51球涛、在swift中用強制解包!一定要非常小心,盡量少用校镐,一不小心程序就崩潰了亿扁;


52、在swift中數(shù)組和字典都屬于值類型鸟廓,相當于int類型从祝,跟oc不一樣,當你把數(shù)組賦值給另一個數(shù)組引谜,修改數(shù)組的值不會影響另一個數(shù)組牍陌;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市员咽,隨后出現(xiàn)的幾起案子毒涧,更是在濱河造成了極大的恐慌,老刑警劉巖贝室,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件链嘀,死亡現(xiàn)場離奇詭異,居然都是意外死亡档玻,警方通過查閱死者的電腦和手機怀泊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來误趴,“玉大人霹琼,你說我怎么就攤上這事×沟保” “怎么了枣申?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長看杭。 經(jīng)常有香客問我忠藤,道長,這世上最難降的妖魔是什么楼雹? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任模孩,我火速辦了婚禮尖阔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘榨咐。我一直安慰自己介却,他們只是感情好,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布块茁。 她就那樣靜靜地躺著齿坷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪数焊。 梳的紋絲不亂的頭發(fā)上永淌,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機與錄音佩耳,去河邊找鬼遂蛀。 笑死,一個胖子當著我的面吹牛蚕愤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播饺蚊,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼萍诱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了污呼?” 一聲冷哼從身側(cè)響起裕坊,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎燕酷,沒想到半個月后籍凝,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡苗缩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年饵蒂,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酱讶。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡退盯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出泻肯,到底是詐尸還是另有隱情渊迁,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布灶挟,位于F島的核電站琉朽,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏稚铣。R本人自食惡果不足惜箱叁,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一墅垮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蝌蹂,春花似錦噩斟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至齐鲤,卻和暖如春斥废,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背给郊。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工牡肉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人淆九。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓统锤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親炭庙。 傳聞我的和親對象是個殘疾皇子饲窿,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

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