ios分层设计 野指针问题

把昨天代码重构了下分层

Xcode6.2没有直接生成两个文件的class操作 仔细寻找后找到 新建 new file -> Source -> Cocoa Touch Class 直接生成一个h和一个m俩文件

事先将xib建好

新建纯净view 自定义xib class为RowView

xib里面去掉layou out 选择freestate 来更高宽高属性 拖放两个按钮一个文本标签

分别给予tag赋值1.2.3

 1 //
 2 //  RowView.h
 3 //  08-通讯录
 4 //
 5 //  Created by zjj on 15/5/12.
 6 //  Copyright (c) 2015年 zjj. All rights reserved.
 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 
11 @interface RowView : UIView
12 + (id)rowViewWithIcon :(NSString *)icon name :(NSString *)name;
13 @end
 1 //
 2 //  RowView.m
 3 //  08-通讯录
 4 //
 5 //  Created by zjj on 15/5/12.
 6 //  Copyright (c) 2015年 zjj. All rights reserved.
 7 //
 8 
 9 #import "RowView.h"
10 
11 @implementation RowView
12 + (id)rowViewWithIcon:(NSString *)icon name:(NSString *)name
13 {
14   RowView *view = [[NSBundle mainBundle]loadNibNamed:@"RowView" owner:nil options:nil][0];
15     UIButton *btnIcon = (UIButton *)[view viewWithTag:1];
16     [btnIcon setImage:[UIImage imageNamed:icon] forState:UIControlStateNormal];
17     UILabel *labName = (UILabel *)[view viewWithTag:2];
18     labName.text = name;
19     return view;
20 }
21 @end

ViewController.m局部代码

1 #import "RowView.h"
2 #pragma mark 用自定义xib创建一行view并添加文字和头像
3 - (UIView *)createRowView
4 {
5     NSString *iconNames = [NSString stringWithFormat:@"0%d.jpg",arc4random_uniform(9)];
6     NSString *name = _allNames[arc4random_uniform((int)_allNames.count)];
7     RowView *rowView = [RowView rowViewWithIcon:iconNames  name:name];
8     return rowView;
9 }

ViewController.m全代码文件

  1 //
  2 //  ViewController.m
  3 //  08-通讯录
  4 //
  5 //  Created by zjj on 15/5/10.
  6 //  Copyright (c) 2015年 zjj. All rights reserved.
  7 //
  8 
  9 #import "ViewController.h"
 10 #import "RowView.h"
 11 #define kDuation 0.5
 12 #define kRowH 50
 13 #define kNameTag 10
 14 //类扩展 (class extension 匿名分类)用于扩展 内部可以声明本类全局引用私有变量
 15 @interface ViewController ()
 16 {
 17     CGFloat _rowY ;
 18     NSArray *_allNames; // 苹果官方规则成员变量必须以下划线开头
 19 }
 20 @end
 21 
 22 @implementation ViewController
 23 #pragma mark 控制器的view加载完毕的时候调用一次
 24 - (void)viewDidLoad
 25 {
 26     [super viewDidLoad];
 27     _allNames = @[@"加菲猫吃饭",@"加菲猫打瞌睡",@"加菲猫喝茶",@"加菲猫乘地铁",@"加菲猫敲代码",@"加菲猫打电话",@"加菲猫听音乐",@"加菲猫起床",@"加菲猫奶孩子"];
 28 
 29 }
 30 #pragma mark 添加一行
 31 - (IBAction)add:(UIBarButtonItem *)sender {
 32     // 0取出最后一个子控件
 33     UIView *lastView = [self.view.subviews lastObject];
 34     // 这行的Y =  最后一个控件的Y值+控件的高度+间距
 35     _rowY = lastView.frame.origin.y + lastView.frame.size.height + 5;
 36     // 创建一行
 37     UIView *rowView = [self createRowView];
 38     NSLog(@"%@",rowView);
 39     // 添加一行到控制器view中
 40     [self.view addSubview:rowView];
 41     _removes.enabled = YES;// 启用删除
 42     // 设置动画开始前的控件属性
 43     rowView.frame = CGRectMake(375, _rowY, 375, 50);
 44     rowView.alpha = 0;// 设置透明度
 45     // 执行动画
 46     [UIView animateWithDuration:kDuation animations:^{
 47         // 改变控件属性
 48         rowView.frame = CGRectMake(0, _rowY, 375, 50);
 49         rowView.alpha = 1;
 50     }];
 51 }
 52 #pragma mark 创建一行 添加头像和文字
 53 //- (UIView *)createRowView
 54 //{
 55 //    // 1.添加父控件
 56 //    UIView *rowView = [[UIView alloc]init];
 57 //    rowView.frame = CGRectMake(0, _rowY, 375, 50);
 58 //    rowView.backgroundColor  = [UIColor whiteColor];
 59 //    // 2.添加文字
 60 //    UILabel *name = [[UILabel alloc]init];
 61 //    name.frame = CGRectMake(0, 0, self.view.frame.size.width, kRowH);
 62 //    name.text = _allNames[arc4random_uniform((int)_allNames.count)];
 63 //    name.textAlignment = UITextAlignmentCenter;
 64 //    name.backgroundColor = [UIColor clearColor];
 65 //    name.tag = kNameTag;
 66 //    [rowView addSubview:name];
 67 //    // 3.添加头像 创建子控件 添加到父控件行中
 68 //    UIButton *icon = [UIButton buttonWithType:UIButtonTypeCustom];
 69 //    icon.frame = CGRectMake(20, 0, 50, kRowH);
 70 //    //创建随机头像
 71 ////    int randomIndex = arc4random() % 9;//取0-8随机整数(老写法)
 72 //    int randomIndex = arc4random_uniform(9);//取0-8随机整数
 73 //    NSString *imgNames = [NSString stringWithFormat:@"0%d.jpg",randomIndex];
 74 //    UIImage *img = [UIImage imageNamed:imgNames];
 75 //    // 给按钮添加监听器
 76 //    [icon addTarget:self action:@selector(iconClick:) forControlEvents:UIControlEventTouchUpInside];
 77 //    //保持头像宽高不变形
 78 //    [icon setImage:img forState:UIControlStateNormal];
 79 //    [rowView addSubview:icon];
 80 //    // 删除按钮
 81 //    UIButton *delete = [UIButton buttonWithType:UIButtonTypeRoundedRect];
 82 //    delete.frame = CGRectMake(320, 0, 60, 60);
 83 //    [delete setTitle:@"删除" forState:UIControlStateNormal];
 84 //    [delete addTarget:self action:@selector(delClick:) forControlEvents:UIControlEventTouchUpInside];
 85 //    [rowView addSubview:delete];
 86 //    return rowView;
 87 //}
 88 #pragma mark 用xib创建一行并添加文字和头像
 89 //- (UIView *)createRowView
 90 //{
 91 //    // 0.加载RowView文件,创建Objects数组按顺序包装所有控件到数组中返回 xib = nib app打包时候自动生成xib文件
 92 //   NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"RowView" owner:self options:nil];
 93 //    // 1.取出一行view
 94 //    UIView *rowViews = views[0];
 95 //    // 2.设置头像
 96 //    UIButton *imgBtn = (UIButton *)[rowViews viewWithTag:1];
 97 //    NSString *names = [NSString stringWithFormat:@"0%d.jpg",arc4random_uniform(9)];
 98 //    // 2.1设置头像按钮背景图 随机获取头像
 99 //    [imgBtn setImage:[UIImage imageNamed:names] forState:UIControlStateNormal];
100 //    // 2.2添加头像点击监听
101 //    [imgBtn addTarget:self action:@selector(iconClick:) forControlEvents:UIControlEventTouchUpInside];
102 //    // 3.设置描述
103 //    UILabel *lab = (UILabel *)[rowViews viewWithTag:2];
104 //    // 3.1随机获取描述信息
105 //    lab.text =_allNames[arc4random_uniform((int)_allNames.count)];
106 ////    // 4.设置删除按钮
107 ////    UIButton *delBtn = (UIButton *)[rowViews viewWithTag:3];
108 ////    // 4.1添加删除点击监听
109 ////    [delBtn addTarget:self action:@selector(delClick:) forControlEvents:UIControlEventTouchUpInside];
110 //    return rowViews;
111 //}
112 #pragma mark 用自定义xib创建一行view并添加文字和头像
113 - (UIView *)createRowView
114 {
115     NSString *iconNames = [NSString stringWithFormat:@"0%d.jpg",arc4random_uniform(9)];
116     NSString *name = _allNames[arc4random_uniform((int)_allNames.count)];
117     RowView *rowView = [RowView rowViewWithIcon:iconNames  name:name];
118     return rowView;
119 }
120 #pragma mark 监听删除按钮点击
121 - (void)delClick :(UIButton *)btn
122 {
123     [UIView animateWithDuration:kDuation animations:^{
124         // 移动待删除行整体移动到右方
125         CGRect  tempF = btn.superview.frame;
126         tempF.origin.x = 375;
127         btn.superview.frame = tempF;
128         btn.superview.alpha = 0;
129     } completion:^(BOOL finished) {
130         // 1.获得即将删除这行 仔数组中的位置
131         int startIndex = (int)[self.view.subviews indexOfObject:btn.superview];
132         // 3.删除当前行
133         [btn.superview removeFromSuperview];
134         [UIView animateWithDuration:kDuation animations:^{
135         // 2.遍历子控件 自动上移删除行下方子控件
136         for (int i = startIndex; i < self.view.subviews.count; i++) {
137             UIView *child = self.view.subviews[i];
138             CGRect tempF = child.frame;
139             tempF.origin.y -= kRowH + 1;// 添加时候是每行+1
140             child.frame = tempF;
141         }
142         }];
143         // 4.判断垃圾桶
144         _removes.enabled = self.view.subviews.count > 1;
145     }];
146 }
147 #pragma mark 监听头像点击
148 - (void)iconClick :(UIButton *)btn
149 {
150     // 1.取得按钮的父控件(因为lable和btn在同一父控件)
151     // 获得按钮点击行的文本标签
152     UILabel *label = (UILabel *)[btn.superview viewWithTag:2];
153 //    NSLog(@"iconClick%f",btn.superview.frame.origin.y);
154     NSLog(@"%@",label.text);
155 }
156 
157 #pragma mark 删除一行
158 - (IBAction)remove:(UIBarButtonItem *)sender {
159     UIView *lastView = [self.view.subviews lastObject];
160     [UIView animateWithDuration:kDuation animations:^{
161         CGRect tempF = lastView.frame;
162         tempF.origin.x = 375;
163         lastView.frame = tempF;
164         lastView.alpha = 1;
165     } completion:^(BOOL finished) {//动画执行完毕后自动调用这个代码段
166              [lastView removeFromSuperview];
167         // 剩下子控件个数大于1才能点击删除 c语言写法
168         _removes.enabled = self.view.subviews.count > 1;
169     }];
170 }
171 @end

一运行报错

 unrecognized selector sent to instance 0x7f9d3b56f5c0 UIImage setImage:forstate?
仔细检查这个icon头像按钮发现修改了它默认的Class。重新清空值(默认为UIButton)后运行成功

原文地址:https://www.cnblogs.com/zhangdashao/p/4497772.html