买苹果7p和三星s8哪个好好还是苹果7好

前段时间在做一个离线下载的时候,要手动点击列表中每一个病人的数据,保存到本地,然后在断网的情况下,仍然可以查看病人的电子病历,医嘱,检验等数据。网上一直没找到资料,就在这里做一个简单的总结。wpf 这方面首先就是界面代码 直接上代码&!--列表内容样式--&& & &Style TargetType=&{x:Type ListViewItem}& x:Key=&ListViewItemContainerStylePatientList&&& & & & &Setter Property=&FontSize& Value=&18&/&& & & & &Setter Property=&Height& Value=&60&/&& & & & &Setter Property=&Foreground& Value=&#FF555555&/&& & & & &Setter Property=&HorizontalContentAlignment& Value=&Center& /&& & & & &Setter Property=&Template&&& & & & & & &Setter.Value&& & & & & & & & &ControlTemplate TargetType=&{x:Type ListViewItem}&&& & & & & & & & & & &Border x:Name=&Bd& &Background=&{TemplateBinding Background}& &&& & & & & & & & & & & & & & & & BorderBrush=&{TemplateBinding BorderBrush}& BorderThickness=&0& && & & & & & & & & & & & &GridViewRowPresenter Content=&{TemplateBinding Content}& Columns=&{TemplateBinding GridView.ColumnCollection}&/&& & & & & & & & & & &/Border&& & & & & & & & & & &ControlTemplate.Triggers&& & & & & & & & & & & & &Trigger Property=&IsSelected& Value=&true&&& & & & & & & & & & & & & & &Setter Property=&Background& TargetName=&Bd& Value=&#FFCCCCCC&/&& & & & & & & & & & & & &/Trigger&& & & & & & & & & & &/ControlTemplate.Triggers&& & & & & & & & &/ControlTemplate&& & & & & & &/Setter.Value&& & & & &/Setter&& & & & &!--隔行变色--&& & & & &Style.Triggers&& & & & & & &MultiTrigger&& & & & & & & & &MultiTrigger.Conditions&& & & & & & & & & & &Condition Property=&ItemsControl.AlternationIndex& Value=&1& /&& & & & & & & & &/MultiTrigger.Conditions&& & & & & & & & &Setter Property=&Background& Value=&#F5F5F5& /&& & & & & & &/MultiTrigger&& & & & &/Style.Triggers&& & &/Style&&!--列头样式定义--&& & &Style x:Key=&ListViewHeaderPatientList& TargetType=&{x:Type GridViewColumnHeader}&&& & & & &Setter Property=&OverridesDefaultStyle& Value=&True&/&& & & & &Setter Property=&FontSize& Value=&18&/&& & & & &Setter Property=&Foreground& Value=&White&/&& & & & &Setter Property=&Template&&& & & & & & &Setter.Value&& & & & & & & & &ControlTemplate TargetType=&{x:Type GridViewColumnHeader}&&& & & & & & & & & & &Grid Name=&gird& Height=&44&&& & & & & & & & & & & & &Grid.Background&& & & & & & & & & & & & & & &SolidColorBrush Color=&#FF394053&/&& & & & & & & & & & & & &/Grid.Background&& & & & & & & & & & & & &Border Name=&bd& Padding=&{TemplateBinding Padding}&&& & & & & & & & & & & & & & &ContentPresenter &HorizontalAlignment=&Center& VerticalAlignment=&Center&/&& & & & & & & & & & & & &/Border&& & & & & & & & & & & & &!--&Thumb Name=&PART_HeaderGripper& Template=&{StaticResource ThumbColumnHeaderSpliter}& HorizontalAlignment=&Right& Margin=&0,0,-1,0&/&--&& & & & & & & & & & &/Grid&& & & & & & & & & & &ControlTemplate.Triggers&& & & & & & & & & & & & &Trigger Property=&IsMouseOver& Value=&True&&& & & & & & & & & & & & & & &Setter TargetName=&gird& Property=&Background&&& & & & & & & & & & & & & & & & &Setter.Value&& & & & & & & & & & & & & & & & & & &SolidColorBrush Color=&#CC536680&/&& & & & & & & & & & & & & & & & &/Setter.Value&& & & & & & & & & & & & & & &/Setter&& & & & & & & & & & & & &/Trigger&& & & & & & & & & & & & &Trigger Property=&IsPressed& Value=&True&&& & & & & & & & & & & & & & &Setter TargetName=&gird& Property=&Background&&& & & & & & & & & & & & & & & & &Setter.Value&& & & & & & & & & & & & & & & & & & &SolidColorBrush Color=&#&/&& & & & & & & & & & & & & & & & &/Setter.Value&& & & & & & & & & & & & & & &/Setter&& & & & & & & & & & & & &/Trigger&& & & & & & & & & & &/ControlTemplate.Triggers&& & & & & & & & &/ControlTemplate&& & & & & & &/Setter.Value&& & & & &/Setter&& & &/Style&//上面style只是作为样式,方便运行粘贴。&ListView Grid.Row=&2& x:Name=&LVPatients& Margin=&36,18,36,0& ItemContainerStyle=&{StaticResource ResourceKey=ListViewItemContainerStylePatientList}&&& & & & & & & & & & & & & & & GridViewColumnHeader.Click=&LVPatients_Click& SelectionChanged=&LVPatients_SelectionChanged& &AlternationCount=&2&& & & & & & & & & & & & & & & & BorderThickness=&0& &&ListView.View&& & & & & & & & & & & & & & & & &GridView x:Name=&pList& ColumnHeaderContainerStyle=&{StaticResource ResourceKey=ListViewHeaderPatientList}&&& & & & & & & & & & & & & & & & & & &GridViewColumn Header=&姓名& DisplayMemberBinding=&{Binding NAME}& &Width=&100&/&& & & & & & & & & & & & & & & & & & &GridViewColumn Header=&性别& DisplayMemberBinding=&{Binding GENDER}& Width=&65&/&& & & & & & & & & & & & & & & & & & &GridViewColumn Header=&年龄& DisplayMemberBinding=&{Binding AGE}& Width=&70&/&& & & & & & & & & & & & & & & & & & &GridViewColumn Header=&住院号/门诊号& DisplayMemberBinding=&{Binding PATIENTSNO}& Width=&140& /&& & & & & & & & & & & & & & & & & & &GridViewColumn Header=&类型& DisplayMemberBinding=&{Binding TREATTYPE}& Width=&90&/&& & & & & & & & & & & & & & & & & & &GridViewColumn Header=&床号& DisplayMemberBinding=&{Binding BEDNO}& Width=&80&/&& & & & & & & & & & & & & & & & & & &GridViewColumn Header=&科室& DisplayMemberBinding=&{Binding DEPTNAME}& Width=&140&/&& & & & & & & & & & & & & & & & & & &GridViewColumn Header=&入院时间& DisplayMemberBinding=&{Binding PATIENTSTARTTIME}& Width=&215&/&& & & & & & & & & & & & & & & & & & &GridViewColumn x:Name=&GCIN& Header=&离线下载& Width=&115&&& & & & & & & & & & & & & & & & & & & & &GridViewColumn.CellTemplate&& & & & & & & & & & & & & & & & & & & & & & &DataTemplate&& & & & & & & & & & & & & & & & & & & & & & & & &Button Width=&100& Background=&Transparent& Height=&50& Content=&{Binding ISDOWNLOADOFFLINEDATA}& &Click=&BtnOffLineData_Click& & & & & & & & & & & & & & & & & & & & & & & & & & &BorderThickness=&0& FontSize=&16& /&& & & & & & & & & & & & & & & & & & & & & & &/DataTemplate&& & & & & & & & & & & & & & & & & & & & &/GridViewColumn.CellTemplate&& & & & & & & & & & & & & & & & & & &/GridViewColumn&& & & & & & & & & & & & & & & & &/GridView&& & & & & & & & & & & & & & &/ListView.View&& & & & & & & & & & & & &/ListView&这里面就是需要在&&GridViewColumn&列下面加一个&GridViewColumn.CellTemplate&子模板,然后给一个数据模板 绑定数据& & & & & & & & & & & & & & & & & & & & & & &DataTemplate&& & & & & & & & & & & & & & & & & & & & & & & & &Button Width=&100& Background=&Transparent& Height=&50& Content=&{Binding ISDOWNLOADOFFLINEDATA}& &Click=&BtnOffLineData_Click& & & & & & & & & & & & & & & & & & & & & & & & & & &BorderThickness=&0& FontSize=&16& /&& & & & & & & & & & & & & & & & & & & & & & &/DataTemplate&& & & & & & & & & & & & & & & & & & & & &/GridViewColumn.CellTemplate&这里的点击事件就是分别处理每一行的点击事件 操作数据& & & & //这里就是拿到绑定数据该行对象 继续执行下一步操作& & & & private void BtnOffLineData_Click(object sender, RoutedEventArgs e)& & & & {& & & & & & var btn = sender as B& & &&& & & & & & EntityPatient player = btn.DataContext as EntityP& & & & & && & & & }
最新教程周点击榜
微信扫一扫Cell网络请求数据的处理 - 简书
Cell网络请求数据的处理
这里总结的是cell请求和返回数据许多细节方面的处理项目地址:一
自定义cell
一般当系统不能满足我们的需求时,就要自定义
发现cell固定,大小相同的时候勾选Xib,今后的cell从Xib中加载
cell一般要到缓存池中取,缓存池中没有就注册,重新创建
注册时Xib中要设置Identifier为:tag
勾选Xib的时候用registerNib
没有的时候用registerClass
Xib是固定的,可以设置一个高度为70
有关于cell之间的分割线的设置
系统的满足不了我们了要求太粗,我们需要自定义分割线,一般有两种方法
首先设置cell的的高,去掉系统自带的分割线
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = @"推荐标签";
self.view.backgroundColor = CYCommonBgC
// 设置行高
self.tableView.rowHeight = 70;
// 去掉系统自带的分割线
self.tableView.separatorStyle = UITableViewCellSeparatorStyleN
然后再考虑怎么设置分割线
方法一:添加一个UIView(设置它的frame:距左,右,下为0 。设定高为1,透明度为0.2)
但是这种方法带来了许多的子控件,当我们的cell较多的时候不推荐这种方法
方法二:保持cell的位置不变,高度都减1
这样就可以少许多的子控件
但是这样又有一些细节和注意的地方。分析如下:
有人会想在下面的cellForRowAtIndexPath:方法中修改cell的frame
但是这是不可能的。因为这里是返回indexPath位置对应的cell,你如果是在这里修改后,一旦return cell。
又会被TableView(系统)重新计算IndexPath对应cell的高度(前面你有有设定cell高度为70),frame等
循环利用,又会被系统修改回去
所以别想着在这里修改cell的frame
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
CYTagCell *cell = [tableView dequeueReusableCellWithIdentifier:@"tag"];
也有人可能会想着实现代理方法,在下面的didSelectRowAtIndexPath:方法中修改cell的高度,每选中一次就让它的高度减1也可以实现分割线
但是:同样的在上面的cellForRowAtIndexPath:方法中,用户一做上拉操作,就会循环利用,cell的高又会被系统重新修改回去
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
CYTagCell *cell = (CYTagCell *)[tableView cellForRowAtIndexPath:indexPath];
cell.height -= 1;
所以存在的问题:自己手动修改了cell的frame后,很有可能会被系统改回去
那么解决的方案:在系统设置完cell的frame后,自己再手动修改cell的frame, 重写setFrame:方法
重写这个方法的目的:拦截cell的frame设置,系统改完后,我再改,永远改在系统的后面
不用担心高度会递减,前面有设置cell的高度为70,在每次传进cell高度减1前,cell都会重新设置高度为原来的70
- (void)setFrame:(CGRect)frame
frame.size.height -= 1;
[super setFrame:frame];
重写setFrame:方法引申出来的价值
1.当我们今后要拦截系统的某些设置(frame,size等),某些操作(像push)的时候。我们就要想到是不是可以去重写它们相应的方法
2.今后如果我们自定义的控件有一些特殊的需求,不希望外界可以轻松修改我们内部的值(像frame,size等)。或者是为了避免外界误传值修改了尺寸等值,我们就可以重写setFrame:方法
当然别也可以通过修改bounds来修改尺寸,你就还得重写setBounds:方法,人家也还可以通过修改transform来修改,你就还得重写setTransform:方法。一般不会如此变态
只是说记得有这么个细节和问题,知道可以这么干
设置左右间距
x向右移动一个你定的间距margin,然后width减2倍间距margin
就设置好了cell的分割线,以及左右间隔或者是左右间隔线
- (void)setFrame:(CGRect)frame
frame.size.height -= 1;
frame.origin.x = 5;
frame.size.width -= 2 * frame.origin.x;
[super setFrame:frame];
网络请求真实的数据
首先,要注意的地方:
使用Xcode7进行数据请求时
苹果新特性要求App内访问网络请求,要采用 HTTPS 协议
但是现在公司的项目使用的是 HTTP 协议,使用私有加密方式保证数据安全。现在也不能马上改成 HTTPS 协议传输。
解决办法:
在Info.plist中添加 NSAppTransportSecurity 类型 Dictionary
在 NSAppTransportSecurity 下添加 NSAllowsArbitraryLoads 类型Boolean ,值设为 YES
方式一: 使用文本编辑Info.plist, 在当中添加:
&key&NSAppTransportSecurity&/key&
&key&NSAllowsArbitraryLoads&/key&
方式二: 在Info.plist中添加:
发送请求给服务器,获取数据
加载标签数据
使用AFNetworking框架
先要根据API文档请求参数
参数是一个字典,里面有各种参数
// 加载标签数据
// 请求参数
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"a"] = @"tag_recommend";
params[@"action"] = @"sub";
params[@"c"] = @"topic";
// 发送请求
[[AFHTTPSessionManager manager] GET:@"/api/api_open.php" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {
// 将服务器的数据写成plist。方便查看数据结构
[responseObject writeToFile:@"/Users/gecongying/Desktop/tag.plist" atomically:YES];
} failure:^(NSURLSessionDataTask *task, NSError *error) {
一般开发的适合你可以将服务器的数据写成plist。这样方便查看数据结构
可以看出plist文件中有许多的字典数组,所以我们要将字典转模型
字典转模型时,公司的服务器可能传回来一堆的数组,但是真正用到可以用于显示的数据只有几个,没必要每个都写,只取我需要的
像这里只需要用到“头像”“订阅数”“name”三个数据
字典数组转模型数组。所以搞一个模型数组(新建标签模型CYTag)(方便开发),这里选用MJExtension框架
在CYTag.h文件中
#import &Foundation/Foundation.h&
@interface CYTag : NSObject
/** 图片 */
@property (nonatomic, copy) NSString *image_
/** 订阅数 */
@property (nonatomic, assign) NSInteger sub_
// 这里用NSInteger是为了后面更好的处理数字
/** 名字 */
@property (nonatomic, copy) NSString *theme_
在CYTagViewController.m文件中
用一个标签数组保存标签数据(里面放的是CYTag模型)
#import "CYTagViewController.h"
#import "CYTagCell.h"
#import &AFNetworking.h&
#import &MJExtension.h&
#import "CYTag.h"
@interface CYTagViewController ()
/** 所有的标签数据(里面存放的都是CYTag模型) */
@property (nonatomic, strong) NSArray *
@implementation CYTagViewController
在TableView数据源方法中,cell返回的个数
#pragma mark - &UITableViewDataSource&
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return self.tags.
在CYTagCell.Xib文件中,将cell中的控件以及控件之间的束设置好。
要把模型数组显示到cell对应的位置,所以得进行拖线,拖到CYTagcell.m文件中
@interface CYTagCell()
@property (weak, nonatomic) IBOutlet UIImageView *imageListV
@property (weak, nonatomic) IBOutlet UILabel *themeNameL
@property (weak, nonatomic) IBOutlet UILabel *subNumberL
字典转模型
字典转模型后要记得刷新表格
// 发送请求
[[AFHTTPSessionManager manager] GET:@"/api/api_open.php" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {
// 将服务器的数据写成plist。方便查看数据结构
// [responseObject writeToFile:@"/Users/gecongying/Desktop/tag.plist" atomically:YES];
// responseObject:字典数组
// self.tags:模型数组
// responseObject -& self.tags
// 字典数组转模型数组
self.tags = [CYTag objectArrayWithKeyValuesArray:responseObject];
// 刷新表格
[self.tableView reloadData];
} failure:^(NSURLSessionDataTask *task, NSError *error) {
CYTagCell内部要拿到相应的数据,所以也需要有标签模型
下面的命名之所以用tagModel而不用tag
因为系统控件基本都有tag属性,取名不正确会被系统覆盖
所以有时候取名也得注意
@interface CYTagCell : UITableViewCell
/** 标签模型 */
@property (nonatomic, strong) CYTag *tagM
setTagModel
- (void)setTagModel:(CYTag *)tagModel
_tagModel = tagM
self.themeNameLabel.text = tagModel.theme_
self.subNumberLabel.text = tagModel.sub_
字典转模型,基本就以下三行代码:
* 返回indexPath位置对应的cell
-(UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath
CYTagCell *cell = [tableView dequeueReusableCellWithIdentifier:@"tag"];
cell.tagModel = self.tags[indexPath.row];
现在只剩下图片的下载
以及显示下载的图片,名字,以及订阅数
在CYTagCell.m文件中用SDWebImage框架下载和显示图片
订阅数-有关于数字的处理
大于一万(tagModel.sub_number / 10000.0)与不到一万的处理
%.1f万人订阅--多少万人订阅,并保留1位小数
- (void)setTagModel:(CYTag *)tagModel
_tagModel = tagM
// 下载头像(SDWebImage框架给了一个占位图片defaultUserIcon)
[self.imageListView sd_setImageWithURL:[NSURL URLWithString:tagModel.image_list] placeholderImage:[UIImage imageNamed:@"defaultUserIcon"]];
self.themeNameLabel.text = tagModel.theme_
// tagModel.sub_number = 678;
// 有关于数字的处理
if (tagModel.sub_number &= 10000) {
self.subNumberLabel.text = [NSString stringWithFormat:@"%.1f万人订阅", tagModel.sub_number / 10000.0];
self.subNumberLabel.text = [NSString stringWithFormat:@"%zd人订阅", tagModel.sub_number];
关于订阅数显示,可以加tagModel.sub_number = 678这句代码,用这样的假数据测试一下
显示结果:
细节处理部分
用户网速慢的时候,网络有延迟的时候
用户网速慢,网络有延迟的时候。会出现跳转后,没有内容,空白一片
下面模拟一下网速慢的时候出现的上述情况
// 发送请求
[[AFHTTPSessionManager manager] GET:@"/api/api_open.php" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 *NSEC_PER_SEC)), dispatch_get_main_queue(),^{
self.tags = [CYTag objectArrayWithKeyValuesArray:responseObject];
[self.tableView reloadData];
用SVProgressHUD框架
在数据加载请求前先弹一个框,数据请求成功后再隐藏掉
这里是为了用户体验更好(网络慢,人家一进来就是一片空白什么鬼)
也为了防止用户在数据请求前做操作或是直接点击离开界面(数据还没到呢)
[SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeBlack];
数据回来后关闭弹框
[SVProgressHUD dismiss];
为了严谨期间,数据加载失败情况下,也要弹框
1.服务器出现问题,返回数据为空
2.请求路径出错
# pragma mark- 专门加载标签数据
- (void)loadTags
[SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeBlack];
[SVProgressHUD show];
// 请求参数
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"a"] = @"tag_recommend";
params[@"action"] = @"sub";
params[@"c"] = @"topic";
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 发送请求
[[AFHTTPSessionManager manager] GET:@"/api/api_open.php" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {
if (responseObject == nil) {
// 关闭弹框
[SVProgressHUD showErrorWithStatus:@"加载标签数据失败"];
self.tags = [CYTag objectArrayWithKeyValuesArray:responseObject];
// 刷新表格
[self.tableView reloadData];
// 关闭弹框
[SVProgressHUD dismiss];
} failure:^(NSURLSessionDataTask *task, NSError *error) {
// 关闭弹框
[SVProgressHUD showErrorWithStatus:@"加载标签数据失败"];
今后遇上此种网络请求问题,一定记得给用户弹框啊
但是这样处理了还有隐患
隐患一:假如数据请求不到的时候,你就会一直在那儿弹框
隐患二:用户仍然可以点击上面的返回键,但是到了上一个界面,你还是在弹框
这又要怎么办呢?用户体验不行啊
方法一:在dealloc:方法中dismiss一下
- (void)dealloc
[SVProgressHUD dismiss];
方法二:在控制器即将消失前dismiss掉(此法较为霸道)
- (void)viewWillDisappear:(BOOL)animated
[super viewWillDisappear:animated];
[SVProgressHUD dismiss];
在实际开发中遇上的问题
也是AFN框架自己的小问题
用AFN框架的block时建议使用弱引用weakSelf
# pragma mark- 专门加载标签数据
- (void)loadTags
[SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeBlack];
[SVProgressHUD show];
// 加载标签数据
// 请求参数
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"a"] = @"tag_recommend";
params[@"action"] = @"sub";
params[@"c"] = @"topic";
// 发送请求
__weak typeof(self) weakSelf =
[self.manager GET:@"/api/api_open.php" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {
if (responseObject == nil) {
// 关闭弹框
[SVProgressHUD showErrorWithStatus:@"加载标签数据失败"];
// responseObject:字典数组
// weakSelf.tags:模型数组
// responseObject -& weakSelf.tags
weakSelf.tags = [CYTag objectArrayWithKeyValuesArray:responseObject];
// 刷新表格
[weakSelf.tableView reloadData];
// 关闭弹框
[SVProgressHUD dismiss];
} failure:^(NSURLSessionDataTask *task, NSError *error) {
// 关闭弹框
[SVProgressHUD showErrorWithStatus:@"加载标签数据失败"];
分析要用弱引用self的原因
因为用了self,成功success的block对我们self的控制器有一个强引用(这是因为manager有字典,它强引用着block。只要manager不死,block就不会死)这样的话控制器是不死的
只有block死,self才会死,控制器也就才会死--这个时候没有block強指针指着它了
而block只有请求完毕,调用完block后,那些代理方法删除后才会死(在didCompleteWithError:(请求完毕)方法中有一句:removeDelegateForTask)只有在这个时候,移除了一些代理方法后,block才会死
那么控制器只有在服务器那儿请求完毕后才会销毁(也就是网络慢的时候的情况
所以用弱引用self
这样意味着,不管block死不死,我的控制器都不会被强引用着
网络请求仍有细节问题
当发送请求时,网速慢,用户点击返回后,虽然控制器挂了,但是AFN内部仍然在请求网络数据,在浪费用户的流量
所以要在控制器挂掉前,停止请求数据
AFN请求数据主要由manager,所以要给manager设个属性,不管强弱(AFN内部早就封装存储好了,但最好是弱引用)
一般框架内部的东西,我们最好用弱引用好些
然后进行懒加载
/** 请求管理者 */
@property (nonatomic, weak) AFHTTPSessionManager *
@implementation CYTagViewController
- (AFHTTPSessionManager *)manager
if (!_manager) {
_manager = [AFHTTPSessionManager manager];
在dealloc:方法中,AFN内部有方法,让所有对象执行cancel方法,停止请求
今后要管理AFN的所有任务,只要拿到manager就行了-
判断是取消任务(code = -999)还是返回数据(域名,服务器,URL等)
# pragma mark- 专门加载标签数据
- (void)loadTags
[SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeBlack];
[SVProgressHUD show];
// 加载标签数据
// 请求参数
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"a"] = @"tag_recommend";
params[@"action"] = @"sub";
params[@"c"] = @"topic";
// 发送请求
__weak typeof(self) weakSelf =
[self.manager GET:@"/api/api_open.php" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {
if (responseObject == nil) {
// 关闭弹框
[SVProgressHUD showErrorWithStatus:@"加载标签数据失败"];
// responseObject:字典数组
// weakSelf.tags:模型数组
// responseObject -& weakSelf.tags
weakSelf.tags = [CYTag objectArrayWithKeyValuesArray:responseObject];
// 刷新表格
[weakSelf.tableView reloadData];
// 关闭弹框
[SVProgressHUD dismiss];
} failure:^(NSURLSessionDataTask *task, NSError *error) {
// 如果是取消了任务,就不算请求失败,就直接返回
if (error.code == NSURLErrorCancelled)
if (error.code == NSURLErrorTimedOut) {
// 关闭弹框
[SVProgressHUD showErrorWithStatus:@"加载标签数据超时,请稍后再试!"];
// 关闭弹框
[SVProgressHUD showErrorWithStatus:@"加载标签数据失败"];
- (void)dealloc
// 停止请求
[self.manager invalidateSessionCancelingTasks:YES];
[self.manager.downloadTasks makeObjectsPerformSelector:@selector(cancel)];
[self.manager.dataTasks makeObjectsPerformSelector:@selector(cancel)];
[self.manager.uploadTasks makeObjectsPerformSelector:@selector(cancel)];
[self.manager.tasks makeObjectsPerformSelector:@selector(cancel)];
for (NSURLSessionTask *task in self.manager.tasks) {
[task cancel];
[SVProgressHUD dismiss];
网络请求几个细节总结
1.block里面不用self,用Weakself
2.将manager存起来,方便管理任务Tasks请求
3.有时候服务器返回的数据是空的,严谨起见,弹框提示并return(情况一般少见)
4.在Failure这个block中做事情的时候,一定要分清楚情况:是取消任务还是别的原因来到Failure的
5.控制器挂掉时,一定要将请求关闭,不要浪费用户的流量,并且弹框提示关闭
设置圆角图片
用CALayer设置圆角图片,但是会出现卡屏现象
苹果在渲染的时候做了许多耗时耗能的内部操作
不推荐使用
- (void)awakeFromNib
// 如果使用过于频繁,可能会导致拖拽起来的感觉比较卡
self.imageListView.layer.cornerRadius = self.imageListView.width * 0.5;
self.imageListView.layer.masksToBounds = YES;
运用Quarz2D技术,将圆角图片画上去
if (image == nil)
这句代码很有意义,如果没有返回数据,给一个占位图片
- (void)setTagModel:(CYTag *)tagModel
_tagModel = tagM
// 下载头像(SDWebImage框架给力一个占位图片defaultUserIcon)
[self.imageListView sd_setImageWithURL:[NSURL URLWithString:tagModel.image_list] placeholderImage:[UIImage imageNamed:@"defaultUserIcon"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
// 如果图片下载失败,就不做任何处理,按照默认的做法:显示占位图片
// 下面这句代码的意义是很大的
if (image == nil)
// 开启图形上下文
UIGraphicsBeginImageContext(image.size);
// 获得上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
// 添加一个圆
CGContextAddEllipseInRect(ctx, rect);
// 裁剪(裁剪成刚才添加的图形形状)
CGContextClip(ctx);
// 往圆上面画一张图片
[image drawInRect:rect];
// 获得上下文中的图片
self.imageListView.image = UIGraphicsGetImageFromCurrentImageContext();
// 关闭图形上下文
UIGraphicsEndImageContext();
self.themeNameLabel.text = tagModel.theme_
// 有关于数字的处理
if (tagModel.sub_number &= 10000) {
self.subNumberLabel.text = [NSString stringWithFormat:@"%.1f万人订阅", tagModel.sub_number / 10000.0];
self.subNumberLabel.text = [NSString stringWithFormat:@"%zd人订阅", tagModel.sub_number];
封装一个UIImage的分类
在UIImage+CYExtension.h文件中
#import &UIKit/UIKit.h&
@interface UIImage (CYExtension)
* 返回一张圆形图片
- (instancetype)circleI
* 返回一张圆形图片
+ (instancetype)circleImageNamed:(NSString *)
在UIImage+CYExtension.m文件中
#import "UIImage+CYExtension.h"
@implementation UIImage (CYExtension)
- (instancetype)circleImage
// 开启图形上下文
UIGraphicsBeginImageContext(self.size);
// 获得上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
// 添加一个圆
CGContextAddEllipseInRect(ctx, rect);
// 裁剪(裁剪成刚才添加的图形形状)
CGContextClip(ctx);
// 往圆上面画一张图片
[self drawInRect:rect];
// 获得上下文中的图片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// 关闭图形上下文
UIGraphicsEndImageContext();
+ (instancetype)circleImageNamed:(NSString *)name
return [[self imageNamed:name] circleImage];
封装一个UIImageView设置头像的分类
在UIImageView+CYExtension.h文件中
#import &UIKit/UIKit.h&
@interface UIImageView (CYExtension)
* 设置头像
- (void)setHeader:(NSString *)
在UIImageView+CYExtension.m文件中
#import "UIImageView+CYExtension.h"
#import &UIImageView+WebCache.h&
@implementation UIImageView (CYExtension)
- (void)setHeader:(NSString *)url
[self setCircleHeader:url];
- (void)setRectHeader:(NSString *)url
[self sd_setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"defaultUserIcon"]];
- (void)setCircleHeader:(NSString *)url
// PCH文件中有定义
UIImage *placeholder = [[UIImage imageNamed:@"defaultUserIcon"] circleImage];
[self sd_setImageWithURL:[NSURL URLWithString:url] placeholderImage:placeholder completed:
^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
// 如果图片下载失败,就不做任何处理,按照默认的做法:会显示占位图片
if (image == nil)
weakSelf.image = [image circleImage];
今后不管你是要设置圆角还是直角的头像
只需要一行代码setCircleHeader:url或者是setRectHeader:url就行了
- (void)setHeader:(NSString *)url
[self setCircleHeader:url]; // 只需要改这里了哦
- (void)viewDidLoad {
[super viewDidLoad];
UIImageView *imageView = [[UIImageView alloc] init];
imageView.frame = CGRectMake(100, 100, 100, 100);
[imageView setHeader:@"/img/bd_logo1.png"];
[self.view addSubview:imageView];
1.cocoapods中的框架安装中platform :ios, '6.0'
platform :ios, '6.0'
pod 'AFNetworking'~& 0.8'
这里写7.0,写8.0是有区别的
这是表明你下载的AFNetworking框架只支持iOS6的
如果有些功能只能在iOS7或者是iOS8中才有的,你是用不了的
如果想用最新版的一些功能就改为高版本的iOS8.0
2.DEBUG中宏定义的问题
这里可以创建一个宏,但是规定不能全是小写。如:age = 20;是不可以的
aGe = 20 / age8 = 20这样是可以的
3.有关于weak的问题+ 一个对象死不死主要是看它有没有強指针指着
4.IBOutlet的问题
IBOutlet内部有一个隐藏的强引用,它是由特殊用途的
它的内部有强引用,为了在死之前做某些操作,具体在哪里不清楚,但是不会影响使用,我们能够知道这个现象就可以了。weak的指针是会消失的,但IBOutlet内部有一个强引用引用着,但是系统会在恰当的时候会将它去掉,不会影响weak的死亡时间。只是前后会有点差别,了解一下就好
所以自定义 IBOutlet 控件属性一般也使用 weak
有关于全局变量使用
默认情况下,全局变量是全世界都可以访问的
全局常量的写法
1.仅限于本文件访问
在本文件(.m)中写下面的代码
static 类型 const 常量名 = 常量值;
2.全世界都要访问
1& 在CYConst.m文件中
#import &UIKit/UIKit.h&
类型 const 常量名 = 常量值;
// CYConst.m :定义所有的全局常量
#import &UIKit/UIKit.h&
// 请求路径
NSString * const CYRequestURL = @"/api/api_open.php";
2& 在CYConst.h文件中
#import &UIKit/UIKit.h&
UIKIT_EXTERN 类型 const 常量名;
// CYConst.h :引用所有的全局常量
#import &UIKit/UIKit.h&
// 请求路径
UIKIT_EXTERN NSString * const CYRequestURL;
3& 在pch中包含CYConst.h文件
#import "CYConst.h"
1& 被static修饰的全局变量\常量
1) 仅限于当前文件访问
2) 改变了作用域
2& 被static修饰的局部变量
1) 只会占用一块内存,在整个程序运行过程都不会销毁,只会初始化一次
2) 改变了生命周期,并没有改变作用域
例如:static int const money = 30;
当前文件中你都可以访问,其它文件不行
const只修饰它右边的内容,被const修饰的内容都是常量、都是不能再修改的
int * const p1;
p1是常量,*p1是变量
int const * p2;
p2是变量,*p2是常量
const int * p3;
p3是变量,*p3是常量
const int * const p4;
p4是常量,*p4是常量
int const * const p5;
p5是常量,*p5是常量
extern : 可以引用一个全局变量\常量
今后能用const就用const
只有一块内存,不能被修改
什么时候使用宏什么时候全局变量呢
在程序运行过程中,未确定的那些值,但是又可能经常被用到,就用宏(例如前面定义了一个全局颜色)
而已经完全确定,固定的,全世界又要用的,就用const的全局变量
如果可以的话,Give me a star!
花自飘零水自流

我要回帖

更多关于 三星s8还是苹果8哪个好 的文章

 

随机推荐