OC中属性self.a与_a访问的区别

本文深入探讨了Objective-C中属性的定义及使用方法,对比了直接访问实例变量与通过self访问属性的区别,通过实例展示了不同访问方式对深拷贝属性的影响。

在OC中我们可以通过指令@property定义属性。

OC对属性封装了许多方法,同时也会自动实现一些方法,相比实例变量,感觉更加面向对象些。

一般定义属性的方法如下,在Class Test中定义属性int a。

@interface Test:NSObject
@property int a;
-(void) changeAValue:(int) newValue;
@end

在类的实例方法中,我们可以用下面两种方式来访问a属性:

1、直接用属性名访问:

-(void) changeAValue:(int) newValue
{
    _a = newValue;  // 默认生成的属性成员变量前面会自动加上“_”前缀
}

2、通过self.a的形式访问

-(void) changeAValue:(int) newValue
{
    self.a = newValue;
}

这两种访问方式有区别吗?答案是肯定的。

通过第一种方式访问,其实是类似于C++的访问方式,是直接访问的实例变量并赋值。而第二种方式,并不像其表面那么直观,它其实是通过调用编译器自动生成的对于a变量的赋值函数来实现的。即

-(void) changeAValue:(int) newValue
{
    self.a = newValue; // 此处实际是调用 [self setA:newValue];
}

个人感觉在类中调用自身的属性,还是用self.a的形式比较好。因为它封装了访问方法,加强了我们对变量的控制,也更面向对象些。


为了说明self.a的形式更好用一点,我们可以举个例子。在Class Test中,再添加对象属性NSString* b,并指明其为一个深拷贝属性。

<pre name="code" class="objc">@interface Test:NSObject
@property int a;
@property(copy) NSString* b, *c;
-(void) changeAValue:(int) newValue;
-(void) changeBValue:(NSString*) newBValue andCValue:(NSString*) newCValue;
@end

 

添加实例方法changeBValue:andCValue

<pre name="code" class="objc"><pre name="code" class="objc"><pre name="code" class="objc">-(void) changeBValue:(NSString*) newBValue andCValue:(NSString*) newCValue;
{  

 
   self.b = newBValue;
   _c = newCValue;
}

 
 

在mian函数中写测试用例:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
    
        Test* testObj = [[Test alloc] init];
        NSMutableString* newBValue = [NSMutableString stringWithString:@"Tom"];
        NSMutableString* newCValue = [NSMutableString  stringWithString:@"www3@126.com"];
        [testObj setBValue:<span style="font-family: Arial, Helvetica, sans-serif;">newBValue </span>andCValue:newCValue];
        
        NSLog(@"The value of b is %@ and c is %@", testObj.b, testObj.c);
        [name appendString:@"andLily"];
        [email appendString:@"andLily"];
        NSLog(@"The value of b is %@ and c is %@", testObj.b, testObj.c);

    }
    return 0;
}


运行,得到结果为

技术分享

可以看到,b的值仍然是Tom,而c的值已经跟随这newCValue的值做了改变,末尾添加了“andLily”字符串。

我们的原意是对类属性的赋值应当是深拷贝赋值(在@property声明中添加了copy关键字),但现在b是深拷贝,而c仍然是默认的浅拷贝。究其原因,就是因为一个调用了self来访问,另一个直接对类属性进行了访问。在调用self的赋值方法访问时,编译器会自动根据copy关键字生成对应的深拷贝赋值函数,其实现类似于:

-(void) setB:NSString* newValue
{
    if ( _b! = newValue)
    {
          _b = [newValue copy];
    }
}

b已经和外部不指向同一块内存,因此b的值没有随着外部而改变。

从上面的例子可以看出,我们在类中,应该尽量使用self.a的形式来访问属性,这样对属性的访问会更加可靠简单,否则就需要我们自己实现对应属性的存取方法。


关于类的属性,还有下面几点要注意:

1、类的属性仅在本类中可以访问,子类无法通过_a的形式访问。但是可以通过继承父类的存取方法访问。

2、当声明类的属性后,编译器会自动生成对应的存取方法,但是我们仍然可以通过重写的方式,阻止编译器自动为我们生成存取方法,而是使用我们自己定义的存取方法。

class chk_Conti_zkline: def __init__(self): # self.setWindowFlags(Qt.WindowStaysOnTopHint) self.JOB = os.environ.get('JOB', None) self.STEP = os.environ.get('STEP', None) # self.chklist = os.environ.get('chklist', None) # --启动pycharm.sh时,里面有export INCAM_DEBUG=yes设置此环境变量 INCAM_DEBUG = os.getenv('INCAM_DEBUG', None) # 接口定义 if INCAM_DEBUG == 'yes': # 通过genesis gateway命令连结pid进行会话,不用在genesis环境下运行,直接用gateway的方式,可在pycharm环境下直接debug self.incam = Gateway() # 方法genesis_connect通过查询log-genesis文件获取的料号名 self.JOB = self.incam.job_name self.STEP = self.incam.step_name self.pid = self.incam.pid else: self.incam = InCAM() self.pid = os.getpid() self.ico = ICO(incam=self.incam) self.icNet = ICNET(incam=self.incam) self.jobName = self.ico.SimplifyJobName(jobName=self.JOB) self.dbSite = self.ico.GetDBSite(JOB=self.JOB) self.SITE = self.ico.GetSite(JOB=self.JOB) self.getinfomation_dict = defaultdict(defaultdict) self.ballPadIndexList = defaultdict(list) self.layerMatrix = self.ico.GetLayerMatrix() self.zkLineIndex = defaultdict(defaultdict) self.step_list = self.ico.GetStepList() layer_list = self.ico.GetLayerList() self.zk_siglay = {} self.zkLayerList = self.getZKLayer() # 获取阻抗线层别 for zklay in self.zkLayerList: zkLay_bak = f'{zklay}_bak' self.zkLineIndex[zklay]['zkLaytmp'] = zkLay_bak self.zkLineIndex[zklay]['index'] = [] self.ico.DelLayer(layer_list=[zkLay_bak]) # 创建前先删除 # 删除辅助层 self.ico.DispWork(zklay) self.incam.COM(f'sel_copy_other, dest = layer_name, target_layer ={zkLay_bak},invert = no,dx = 0 ,dy = 0,size= 0,x_anchor= 0,y_anchor = 0') # 复制 self.ico.DispWork(zkLay_bak) # self.incam.COM(f'sel_change_sym, symbol = r3, reset_angle = no') # 缩小线宽为r3(前提是线比r3大) # self.incam.COM("sel_cont_resize,accuracy=0,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=no") # ctrl+F FeatureFullInfo = self.ico.GetFeatureFullInfo(step=self.STEP, layer=zkLay_bak) for info in FeatureFullInfo: info['orig'] = [re.sub(r"\s+", " ", i) for i in info['orig']] for i in info['orig']: if re.search(r'.*#OB.*', i): index_info_list = i.split(' ') self.zkLineIndex[zklay]['index'].append({'x': index_info_list[-3], 'y': index_info_list[-2], 'id': info['id']}) # if re.search(r'.*#OC.*',i): # index_info_list = i.split(' ') # self.zkLineIndex[zklay]['index'].append({'x': index_info_list[-3], 'y': index_info_list[-2],'id': info['id']}) # break # 识别到第一个#OC就break self.ico.DelLayer(layer_list=[f'{zkLay_bak}+++']) # 创建前先删除 # 删除辅助层 self.ico.ClearAll() self.run() def getZKLayer(self): """ 获取阻抗线层别 :return: 阻抗线层别 """ zkLayerList = list() layerList = self.layerMatrix['allLay'] # self.ico.GetLayerList() for lay in layerList: for t in ('s', 'ss', 'gsg', 'gssg'): pattern_tmp = re.compile(r'^((?:un-)?(\d+|[tb])zk)-(\d+\.?\d*)-(%s)-?(\d+\.?\d*)?-?(\d+\.?\d*)?-?(\d+\.?\d*)?$' % t)#存在un开头的阻抗层 matchObj = re.match(pattern_tmp, lay) if matchObj: matchList = matchObj.groups() zkLayerList.append(lay) self.getinfomation_dict[lay]['layer'] = matchList[0] print(zkLayerList) if len(zkLayerList) > 0: SignalLayer_list = self.layerMatrix['sigAllLay'] for i in range(len(SignalLayer_list)): if i == 0: self.zk_siglay['tzk'] = SignalLayer_list[0] elif i == (len(SignalLayer_list) - 1): self.zk_siglay['bzk'] = SignalLayer_list[-1] else: self.zk_siglay[str(i + 1) + 'zk'] = SignalLayer_list[i] self.zk_siglay['un-' + str(i + 1) + 'zk'] = SignalLayer_list[i]#还要加一个un-开头的对应线路层! print("zk_siglay : %s" % self.zk_siglay) for lay in self.getinfomation_dict.keys(): for key in self.zk_siglay: if self.getinfomation_dict[lay]['layer'] == key: self.getinfomation_dict[lay]['sigLayerNum'] = str(SignalLayer_list.index(self.zk_siglay[key]) + 1) self.getinfomation_dict[lay]['sigLayerName'] = str(self.zk_siglay[key]) break else: messageBox.showMessage(message='没有识别到阻抗线层别,请规范命名(eg:tzk-gssg-100)', bitmap='critical') exit() return zkLayerList def get_unique_endpoints(self, job, step, backup_layer): """ 提取 backup_layer 层上所有 line/arc 的端点, 返回仅出现一次的“末端”点(即非连接点) """ features = self.ico.GetFeaturesPro(job=job, step=step, layer=backup_layer) if not features: print(f"[WARN] No features found on layer '{backup_layer}'") return [] endpoints = [] for feat in features: ftype = feat['type'] if ftype == 'line': xs, ys = feat['xs'], feat['ys'] xe, ye = feat['xe'], feat['ye'] endpoints.append((round(xs, 3), round(ys, 3))) endpoints.append((round(xe, 3), round(ye, 3))) elif ftype == 'arc': x_start, y_start = feat['xs'], feat['ys'] x_end, y_end = feat['xe'], feat['ye'] endpoints.append((round(x_start, 6), round(y_start, 6))) endpoints.append((round(x_end, 6), round(y_end, 6))) # 统计每个点出现次数 point_count = defaultdict(int) for pt in endpoints: point_count[pt] += 1 # 只保留只出现一次的点(真正的末端) unique_ends = [pt for pt, cnt in point_count.items() if cnt == 1] unique_ends.sort(key=lambda p: (p[0], p[1])) # 按坐标排序便于调试 print(f"[INFO] Found {len(unique_ends)} unique endpoints on '{backup_layer}'.") return unique_ends def selectun(self, backup_layer, zkLay): """ 完整流程: 1. 复制非 line/arc 图形到 '01' 层 2. 局部合并为独立 surface 3. 提取 backup_layer 的唯一端点 4. 删除覆盖这些端点的 surface 5. 返回状态信息供 run() 使用 """ zk2SigLay = self.getinfomation_dict[zkLay]['sigLayerName'] zkLineIndex = self.zkLineIndex[zkLay]['index'] step = 'edit' ######初始化环境####### self.ico.ClearAll() self.ico.ResetFilter() self.incam.COM(f'afffected_layer, name={backup_layer}, mode=single, affected=yes') self.incam.COM(f'display_layer, name={zk2SigLay}, display=yes') #######处理每根阻抗线,复制并合并 surface 到 '01'层####### for idx, info in enumerate(zkLineIndex): x, y, tmpID = info['x'], info['y'], info['id'] #跨网络选择 self.incam.COM("sel_clear_feat") self.incam.COM("clear_highlight") self.incam.COM(f'sel_board_net_feat, operation=select, x={x}, y={y}, tol=1, use_ffilter=no') #坐标点选 features = self.ico.GetFeatureFullInfo(step=step, layer=zk2SigLay, mode='select') non_line_arcs = [f for f in features if f['type'] not in ('line', 'arc')] if not non_line_arcs: print(f"{backup_layer}层中没有非line非弧图形") continue # 复制到 '01' 层 self.incam.COM( "sel_copy_other, dest=layer_name, target_layer=01, invert=no, " "dx=0, dy=0, size=0, x_anchor=0, y_anchor=0" ) # 切换到 '01' 层进行局部合并 self.ico.DispWork(layer='01') self.incam.COM("sel_clear_feat") self.incam.COM(f"sel_feature, operation=select, x={x}, y={y}, tol=0.3, use_ffilter=no") self.incam.COM('get_select_count') selected_count = int(self.incam.COMANS) if selected_count > 0: self.incam.COM( "sel_cont_resize, accuracy=0, break_to_islands=yes, " "island_size=0, hole_size=0, drill_filter=no, corner_ctl=no" ) #######获取备份层中的唯一端点###### print(f"在{backup_layer}层查找是否有端点坐标") unique_endpoints = self.get_unique_endpoints(job=self.JOB, step=step, backup_layer=backup_layer) if not unique_endpoints: print(f"在{backup_layer}层没有找到端点坐标") # # 仍需检查 01 层状态 # features_01 = self.ico.GetFeaturesPro(job=self.JOB, step=step, layer='01') # return { # 'endpoints_count': 0, # 'surfaces_deleted': 0, # 'remaining_on_01': len(features_01) > 0 # } #############删除 '01' 层中覆盖这些端点的 surface############ print(f"[PHASE 3] Checking {len(unique_endpoints)} endpoints against surfaces on '01'...") self.ico.DispWork(layer='01') self.incam.COM("sel_clear_feat") deleted_surface_count = 0 processed_centers = set() for i, (ux, uy) in enumerate(unique_endpoints): print(f" [CHECK] Endpoint {i+1}: ({ux:.4f}, {uy:.4f})") self.incam.COM("sel_clear_feat") self.incam.COM(f"sel_feature, operation=select, x={ux}, y={uy}, tol=0.01, use_ffilter=no") #在 '01' 层尝试以极小容差(tol=0.01)选择该点附近图形。检查是否有 surface 类型被选中。 self.incam.COM('get_select_count') selected_features = int(self.incam.COMANS) if not selected_features: continue for feat in selected_features: if feat['type'] == 'surface': center_key = (round(feat['x'], 3), round(feat['y'], 3)) if center_key not in processed_centers: print(f" --> Deleting surface at center ({feat['x']:.3f}, {feat['y']:.3f})") processed_centers.add(center_key) deleted_surface_count += 1 #########执行删除############# if deleted_surface_count > 0: self.incam.COM("sel_clear_feat") self.incam.COM('get_select_count') all_surfs = int(self.incam.COMANS) for surf in all_surfs: if surf['type'] == 'surface': key = (round(surf['x'], 3), round(surf['y'], 3)) if key in processed_centers: self.incam.COM(f"sel_feature, operation=select, x={surf['x']}, y={surf['y']}, tol=0.1") self.incam.COM("sel_delete") # === 最终判断 '01' 层是否还有内容 === features_01 = self.ico.GetFeaturesPro(job=self.JOB, step=step, layer='01') has_remaining = len(features_01) > 0 return has_remaining, features_01 # return { # 'endpoints_count': len(unique_endpoints), # 'surfaces_deleted': deleted_surface_count, # 'remaining_on_01': has_remaining # } def selectBallPad(self, zkLay, x, y): """ 判断指定坐标点是否背面ball pad导通 :param zkLay: 阻抗层名称 :param x: 检查点的x坐标 :param y: 检查点的y坐标 :return: bool 是否导通 """ # 阻抗层对应的线路层 zk2SigLay = self.getinfomation_dict[zkLay]['sigLayerName']#self.getinfomation_dict得到的是原始阻抗层,而不是_bak备份阻抗层 sigBot = self.layerMatrix['sigAllLay'][-1] #线路层最后一层,背面 # 设置工作环境 self.ico.ClearAll() self.ico.ResetFilter() self.incam.COM(f'affected_layer, name={sigBot}, mode=single, affected=yes') self.incam.COM(f'display_layer, name={zk2SigLay}, display=yes') self.incam.COM(f'work_layer, name={zk2SigLay}') # 执行选择 self.incam.COM("sel_clear_feat") #清除之前的选择 self.incam.COM("clear_highlight") self.incam.COM(f'sel_board_net_feat, operation=select, x={x}, y={y}, tol=1, use_ffilter=no') # 获取选中特征 featureFullInfo_sigBot = self.ico.GetFeatureFullInfo(step=self.STEP, layer=sigBot, mode='select') # 检查背面ball pad # 对于背面sig选到的物体,做个筛选,如果是pad且是.smd属性,说明选到了ball pad selectPadList = [info for info in featureFullInfo_sigBot if info['type'] == 'pad' and (info['attr'] == '.smd' or info['attr'] == '.smd,.bga' or info['attr'] == '.smd,.lga' or info['attr'] == '.smd,.smt_pad' or info['attr'] == '.smd,.test_pad')] # 20241209 新增ball pad属性.smd.bga和.smd.lga return len(selectPadList) > 0 # 如果找到ball pad则返回True def cleanup_short_polylines(self, step, backup_layer, min_length=8.0): """ 删除总长度 < min_length 的整根 polyline(由多个 line arc 组成) 利用 feature['length'] 避免重复计算几何距离 """ features = self.ico.GetFeatures(step, backup_layer) # 提取所有 line 和 arc valid_features = [f for f in features if f['type'] in ('line', 'arc')] if not valid_features: return # #######构建拓扑图 端点->线段#### graph = defaultdict(list) # 坐标 -> 相邻坐标 coord_to_feats = defaultdict(list) # 坐标 -> (index, feature) for idx, feat in enumerate(valid_features): xs = round(feat['xs'], 3) ys = round(feat['ys'], 3) xe = round(feat['xe'], 3) ye = round(feat['ye'], 3) start = (xs, ys) end = (xe, ye) graph[start].append(end) graph[end].append(start) coord_to_feats[start].append((idx, feat)) coord_to_feats[end].append((idx, feat)) visited_coords = set() short_polyline_seeds = [] # 存储每根短 polyline 的一个起点用于删除 ##########BFS 遍历每个连通组件########### for coord in list(graph.keys()): if coord in visited_coords: continue queue = deque([coord]) current_visited_coords = set() current_feat_indices = set() while queue: curr = queue.popleft() if curr in current_visited_coords: continue current_visited_coords.add(curr) for neighbor in graph[curr]: # 查找连接 curr和neighbor 的 feature found = False for feat_idx, feat in coord_to_feats[curr]: if feat_idx in current_feat_indices: continue # 判断是否连接 curr 和 neighbor s = (round(feat['xs'],3), round(feat['ys'],3)) e = (round(feat['xe'],3), round(feat['ye'],3)) connected = (curr == s and neighbor == e) or (curr == e and neighbor == s) if connected: current_feat_indices.add(feat_idx) found = True break if not found: continue # 没有可用边 if neighbor not in current_visited_coords: queue.append(neighbor) # 标记这些点已被全局访问 visited_coords.update(current_visited_coords) if not current_feat_indices: continue ################计算当前 polyline 总长度########### total_length = sum(valid_features[i]['length'] for i in current_feat_indices) if total_length < min_length: # 找一个端点作为选择依据(度为1的点) endpoints = [pt for pt in current_visited_coords if len(graph[pt]) == 1] seed = endpoints[0] if endpoints else next(iter(current_visited_coords)) short_polyline_seeds.append(seed) ##########删除:选中所有短 polyline######### if short_polyline_seeds: self.incam.COM("sel_clear_feat") for x, y in short_polyline_seeds: self.incam.COM(f"sel_polyline_feat,operation=select,x={x:.3f},y={y:.3f},tol=1") self.incam.COM("sel_delete") def run(self): """ 处理Y形阻抗线检测清理的主执行函数 修改重点: - 每个 backup_layer 单独处理:检测 -> 标记 -> 删除 -> 刷新 - 每次删除后重新获取 features,确保状态最新 - 避免 Entity does not exist 错误 """ job = self.JOB step = 'edit' #在edit层 backup_layers = [] self.ico.ClearAll() self.zkLineIndex = defaultdict(lambda: defaultdict(list)) ######## 创建备份层 ################## for zklay in self.zkLayerList: zkLay_bak = f'{zklay}_bak' self.zkLineIndex[zklay]['zkLaybak'] = zkLay_bak self.ico.DelLayer(layer_list=[zkLay_bak]) self.ico.DispWork(zklay) self.incam.COM(f'sel_copy_other,dest=layer_name,target_layer={zkLay_bak},invert=no,dx=0,dy=0,size=0,x_anchor=0,y_anchor=0') backup_layers.append(zkLay_bak) self.ico.ClearLayer() unthrough_lay = [] ############# 遍历每个 step ############## for backup_layer in backup_layers: original_layer = backup_layer.replace('_bak', '') # self.ico.DispWork(backup_layer) # #############获取当前特征############ features = self.ico.GetFeaturesPro(job, step, backup_layer) if not features: continue # self.incam.COM("sel_clear_feat") # 清空之前选择 has_remaining, features_01 = self.selectun(backup_layer=backup_layer, zkLay=original_layer) if not has_remaining: continue #############待删除坐标的集合(仅针对当前 layer)############ seeds_to_delete = set() ##############判断原线路层中01层touch的阻抗线是否背面的ball pad导通########### for feat in features_01: layer_through = False if feat['type'] not in ('line', 'arc'): continue xs, ys = round(feat['xs'], 3), round(feat['ys'], 3) xe, ye = round(feat['xe'], 3), round(feat['ye'], 3) start_1 = self.selectBallPad(zkLay=original_layer, x=xs, y=ys) end_1 = self.selectBallPad(zkLay=original_layer, x=xe, y=ye) if (start_1 or end_1): layer_through = True break if layer_through: connection_to_ballpad = True # problem_x, problem_y = x, y break # 找到第一个即可跳出 else: seeds_to_delete.add((x, y)) #找到备份层中01层touch的阻抗线 if connection_to_ballpad: # 记录 layer 和坐标 unthrough_lay.append({'layer': backup_layer}) ########统一判断并提示################ if unthrough_lay: lines = [] for pt in unthrough_lay: lines.append(f"{pt['layer']}") # ({pt['x']:.3f}, {pt['y']:.3f}) layer_list_str = ";".join(lines) messageBox.showDialog( title='提示', text=f'以下层存在Y形阻抗线且背面ball pad导通:\n\n{layer_list_str}\n\n' '1、人为确认是否为分流设计\n' '2、如为分流设计,需客户确认是否设计异常,客户EQ此组对抗通过测量科邦卡控阻值,\n' ' 如客户不同意,内部策划列难点评估测科邦', bitmap='warning', buttons=['OK'], defaultButton='OK' ) self.ico.ClearLayer() #############找到孤立不导通线段############ for feat in features: if feat['type'] not in ('line', 'arc'): continue xs, ys = round(feat['xs'], 3), round(feat['ys'], 3) xe, ye = round(feat['xe'], 3), round(feat['ye'], 3) start_ok = self.selectBallPad(zkLay=original_layer, x=xs, y=ys) end_ok = self.selectBallPad(zkLay=original_layer, x=xe, y=ye) if not (start_ok or end_ok): seeds_to_delete.add((xs, ys)) ############执行删除操作 ############ self.incam.COM("sel_clear_feat") # 1. 先清理 <8mm的polyline self.cleanup_short_polylines(job=job, step='edit', backup_layer=backup_layer) # 2. 再删除01层原线路层以及不导通线对应的 polyline current_features = self.ico.GetFeatures(step, backup_layer) # 刷新!重新获取每个备份层的特征,防止 entity not exist valid_coords = {(round(f['xs'],3), round(f['ys'],3)) for f in current_features if f['type'] in ('line','arc')} valid_coords.update({(round(f['xe'],3), round(f['ye'],3)) for f in current_features if f['type'] in ('line','arc')}) for x, y in seeds_to_delete: if (round(x,3), round(y,3)) not in valid_coords: continue # 已被前面的 cleanup 删除,跳过 try: self.incam.COM(f"sel_polyline_feat,operation=select,x={x:.3f},y={y:.3f},tol=1") except: pass # 忽略异常 self.incam.COM("sel_delete") self.ico.ClearLayer() ############判断是否为空层############ features_after = self.ico.GetFeaturesPro(job, step, backup_layer) has_valid = any(f['type'] in ('line', 'arc') for f in features_after) msg = ( f'{backup_layer}存在Y形阻抗线,同组无可测阻抗线,客户EQ此组阻抗通过测量科邦卡控阻值,如客户不同意,内部策划列难点评估测科邦' if not has_valid else f'{backup_layer}存在Y形阻抗线,同组存在可测阻抗线,EQ客户Y型阻抗线follow同组可测阻抗线进行调整' ) messageBox.showMessage( title='提示', text=msg, bitmap='warning', buttons=['OK'], defaultButton='OK' ) self.ico.ClearLayer() sys.exit() if __name__ == "__main__": app = QApplication(sys.argv) analyzer = chk_Conti_zkline() #在run函数中我想要实现:备份所有阻抗层,备份为_bak;对所有备份层的进行线简化,然后对所有line和arc的端点取坐标(通过GetFeaturesPro函数找到‘line’和’arc’属性即可得到), # 接着判断是否存在大于等于3个相同的坐标(重合坐标,同一个坐标点出现超过3次)。没有的话,messagebox提示并结束整个代码; # 如果是的话,接着判断原稿01层的线是否背面的pad导通(selectBallPad函数已经能够实现),导通的话,messagebox提示并结束整个代码; # 没有导通的话,第一:就在备份层阻抗线路删除01层接触的整根线路polyline(注意polyline是一根很长线,由很多短的line组成)self.incam.COM(f"sel_polyline_feat,operation=select,x={feature[‘xs’]},y={feature[‘ys’]}")命令能够通过一个坐标点选中一根polyline # 第二:删除整根线长小于8的polyline;第三:删除不背面ball pad导通的polyline; # 第四:判断经过删除的备份层是否为空,是不是都输出messagebox提示并结束整个代码
11-07
先帮我解析代码 // // SDNQSHardwareLocalAccessSetControllerInfoViewController.h // Omada // // Created by PengXiaochuang on 2020/2/13. // Copyright © 2020 TP-Link. All rights reserved. // #import "SDNQuickSetupSetControllerInfoViewController.h" NS_ASSUME_NONNULL_BEGIN @interface SDNQSHardwareLocalAccessSetControllerInfoViewController : SDNQuickSetupSetControllerInfoViewController @end NS_ASSUME_NONNULL_END // // SDNQSHardwareLocalAccessSetControllerInfoViewController.m // Omada // // Created by PengXiaochuang on 2020/2/13. // Copyright © 2020 TP-Link. All rights reserved. // #import "SDNQSHardwareLocalAccessSetControllerInfoViewController.h" #import "SDNQSHardwareLocalAccessSetScenarioViewController.h" #import "SDNQSHardwareLocalAccessControllerAccessViewController.h" @interface SDNQSHardwareLocalAccessSetControllerInfoViewController () @end @implementation SDNQSHardwareLocalAccessSetControllerInfoViewController - (void)gotoNextPage { self.coordinator.controllerName = self.countrollerName; self.coordinator.selectedCountryName = self.selectedCountryName; self.coordinator.selectedCountryKey = self.selectedCountryKey; self.coordinator.selectedTimezoneName = self.selectedTimezoneName; self.coordinator.selectedTimezoneItem = self.selectedTimeZoneItem; self.coordinator.isAgreePrivacyPolicyOn = self.isAgreePrivacyPolicyOn; self.coordinator.isAgreeUeipOn = self.isAgreeUeipOn; if ([self isSiteSupportSwitchType]) { SDNQSHardwareLocalAccessControllerAccessViewController *vc = [[SDNQSHardwareLocalAccessControllerAccessViewController alloc] init]; [self pushViewController:vc animated:YES]; } else { SDNQSHardwareLocalAccessSetScenarioViewController *vc = [[SDNQSHardwareLocalAccessSetScenarioViewController alloc] init]; [self pushViewController:vc animated:YES]; } } - (BOOL)isSiteSupportSwitchType { return [[TPSDNControllerClient currentInstance].mspDeviceComponent supportForComponent:DMSDNComponentIdSiteSupportSwitchType ForVersionCode:1]; } @end
最新发布
12-10
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值