背景:
一般app運(yùn)營(yíng)位置都會(huì)有類似需求怔匣,需要一個(gè)banner或者按鈕實(shí)現(xiàn)隨意跳轉(zhuǎn)桦沉。我們一般的實(shí)現(xiàn)方式是與服務(wù)端定義特定的type來(lái)跳轉(zhuǎn)特定的頁(yè)面纯露。
問(wèn)題:
業(yè)務(wù)復(fù)雜代芜、增長(zhǎng)較快時(shí),type類型過(guò)多钞速,需要一個(gè)簡(jiǎn)單的跳轉(zhuǎn)就需要維護(hù)新增type并且發(fā)版本來(lái)實(shí)現(xiàn)嫡秕。
思考:
能不能客戶端一次簡(jiǎn)單代碼,之后服務(wù)端想咋跳就咋跳(當(dāng)然某個(gè)版本沒(méi)有這個(gè)類不能跳)驾凶,或者說(shuō)部分想咋跳就咋跳
方案:
通過(guò)runtime掷酗,動(dòng)態(tài)生成類,并且可以傳遞相應(yīng)參數(shù)技肩。具體思路為動(dòng)態(tài)生成類浮声,并且通過(guò)key去修改類的參數(shù)。
代碼:
主要實(shí)現(xiàn)的是跳轉(zhuǎn)到單品頁(yè)并且傳入了相應(yīng)的productId
-(void)runtimeclick {
? ? [self runtimeclickWithclassName:@"productViewController" keyNname:@"productId"];
}
- (void)runtimeclickWithclassName:(NSString * ) VCName keyNname:(NSString *)keyNname {
? ? UIViewController * targetVC = nil;
? ? const char * className = [VCName UTF8String];
? ? Class kclass = objc_getClass(className);
? ? if (kclass)
? ? {
? ? ? ? targetVC = [[kclass alloc]init];
? ? ? ? if (targetVC) {
? ? ? ? ? ? unsigned int count = 0;
? ? ? ? ? ? Ivar * ivar = class_copyIvarList(kclass, &count);
? ? ? ? ? ? ///遍歷屬性,去尋找到name的字段
? ? ? ? ? ? for(int i=0;i
? ? ? ? ? ? {
? ? ? ? ? ? ? ? ///獲取實(shí)例變量
? ? ? ? ? ? ? ? Ivar var = ivar[i];
? ? ? ? ? ? ? ? const char * varName = ivar_getName(var);
? ? ? ? ? ? ? ? ///獲取名字
? ? ? ? ? ? ? ? NSString * name = [NSString stringWithUTF8String:varName];
? ? ? ? ? ? ? ? keyNname = [NSString stringWithFormat:@"_%@",keyNname];
? ? ? ? ? ? ? ? ///判斷名字是不是name屬性
? ? ? ? ? ? ? ? if([name isEqualToString:keyNname])
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? object_setIvar(targetVC, var, @"7894");
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? [self presentViewController:targetVC animated:YES completion:nil];
? ? ? ? ? ? free(ivar);
? ? ? ? }
? ? }
}
總結(jié):
以上知識(shí)簡(jiǎn)單實(shí)用運(yùn)行時(shí)部分方法實(shí)現(xiàn)一個(gè)小的功能。這樣不單解決了業(yè)務(wù)需求同時(shí)代碼也有些代碼解耦的思想筑煮。但是這個(gè)方法偏展示型ViewController粤蝎。有代理或者block或者通知等等需要再添加的還是不能滿足,不過(guò)可以基于此思路擴(kuò)展初澎。