iPhone开发笔记

很多东西不作系统整理记录就很容易遗忘,准备在这里对iPhone开发学习过程作一个回顾整理。

计划从以下几个内容展开:

1. objective c 语法

2. 常用控件

3. 一些传值方法分析,如通知

4. 疑难汇总

……

 -----

9-21初步整理

 

回顾objective c

Objective c是运行时动态语言。

不同于C++的类

1. C++中可以直接使用 . 操作来访问public成员变量,objective c 中在外部进行访问的时候,只能够使用get set 方法

2. objective c 中的类对象在定义的时候,必须使用指针方式

即不能够直接采用这样的方式去定义 classC   c ;

属性

可以用来设置自动生成get set方法

如果设置了属性,在dealloc方法中,使用self.xx = nil; 要好于[xx release];

1.      保持了alloc release的平衡

2.      更加健壮,可以不用去关注成员变量的属性(retain 还是assign

self.xx = nil        等效语句

xx retain        [xx release]; xx = nil;

xx assign        xx = nil;

 

 

在需要多次定义数据结构的时候,可以用一个程序来生成代码,减小工作量

cout << "- (void)dealloc\n{" << endl;

 

for (int i = 0; i < row; i++)

 

{

cout << "    self." << fields[i] << " = nil;" << endl;

 

}

 

 

cout << "\n    [super dealloc];\n}" << endl;

加锁

@synchronized (A) {}  的本质就是根据一个标志A对一段代码进行加锁,开始处lock(sign), 结束时 unlock(sign)

而不是对A进行加锁, A 如同Linux中称谓的互斥量

 

@synchronized (@”00”)

@synchronized (2222)

都是可以的

一般情况下,为了使这个互斥量的值更加的独特,常使用self, 等效于[ClassName class];

 

 

数据的传递

通知机制

典型的观察者模式

根据消息的原理,消息必须释放

 

// remove

[[NSNotificationCenter defaultCenter]removeObserver:self name:ANOTIFNAME object:nil];

 

发送消息 call

[[NSNotificationCenter defaultCenter] postNotificationName: ANOTIFNAME object:theValue];

 

//add

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(atestFun:) name: ANOTIFNAME object:nil];

  

通知的原理

 

通知中心  Menger 中根据通知名称创建数组或者树,字典等结构,这里以数组为例来说明

数组中存放对象的指针,当对象进行设置

[[NSNotificationCenter defaultCenter] postNotificationName: ANOTIFNAME object:theValue];

的时候添加到对应的数组中

 

<array name: ANOTIFNAME>

P1

P2

P3

</array>

 

<array name: ANOTIFNAME2>

 

</array>

 

调用的时候,找到对应的数组,对里面的指针(对象)执行其对应的方法,顺序或者多线程执行

 

如果对象已经释放了,如P1 已经是个野指针,call 的时候,进行方法调用,就会出现崩溃

 

 

 

全局变量

可以通过访问一个全局变量来实现数据的传递

 

其他方法

写文件,数据库

 

 

调试

Gdb的调试方法可以使用

打印查看变量的值

(gdb) p *((UIButton*)0x6d98ce0)

$1 = {

  <UIControl> = {

    <UIView> = {

      <UIResponder> = {

        <NSO

 

  _backgroundView = 0x6dc0210,

  _imageView = 0x0,

  _titleView = 0x6dc00c0,

  _initialized = 1 '\001',

 

(gdb) po 0x6dc00c0

<UIButtonLabel: 0x6dc00c0; frame = (15 6; 58 22); text = ' OK'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x6dc02d0>>

(gdb)

 

po vName  打印一个对象 po  means print object

 

 

指针

对应指针,只需要记住,指针本身是一个变量,占据48个字节(机器位数/8),指针的值,即指针存放的内容,是另外一个变量的地址,可以通过这个地址对该变量进行访问操作

 

野指针

一个野指针错误提示

2012-06-08 17:09:14.418 appTest[64158:fe03] -[UITableViewCell atestFun:]: unrecognized selector sent to instance 0x6bceb20

2012-06-08 17:09:14.813 appTest[64158:fe03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITableViewCell atestFun:]: unrecognized selector sent to instance 0x6bceb20'

*** Call stack at first throw:

(

       0   CoreFoundation                      0x028bcbe9 __exceptionPreprocess + 185

       1   libobjc.A.dylib                     0x02a115c2 objc_exception_throw + 47

       2   CoreFoundation                      0x028be6fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187

       3   CoreFoundation                      0x0282e366 ___forwarding___ + 966

       4   CoreFoundation                      0x0282df22 _CF_forwarding_prep_0 + 50

       5   Foundation                          0x00d996c1 _nsnote_callback + 145

       6   CoreFoundation                      0x02894f99 __CFXNotificationPost_old + 745

       7   CoreFoundation                      0x0281433a _CFXNotificationPostNotification + 186

       8   Foundation                          0x00d8f266 -[NSNotificationCenter postNotificationName:object:userInfo:] + 134

       9   Foundation                          0x00d9b5a9 -[NSNotificationCenter postNotificationName:object:] + 56

       10  appTest                              0x003514d2 -[SelectCityViewController back] + 130

      11  appTest                              0x0035210c -[SelectCityViewController tableView:didSelectRowAtIndexPath:] + 236

       12  UIKit                               0x010a5794 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1140

       13  UIKit                               0x0109bd50 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 219

       14  Foundation                          0x00dae7f6 __NSFireDelayedPerform + 441

       15  CoreFoundation                      0x0289dfe3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19

       16  CoreFoundation                      0x0289f594 __CFRunLoopDoTimer + 1220

       17  CoreFoundation                      0x027fbcc9 __CFRunLoopRun + 1817

       18  CoreFoundation                      0x027fb240 CFRunLoopRunSpecific + 208

       19  CoreFoundation                      0x027fb161 CFRunLoopRunInMode + 97

       20  GraphicsServices                    0x02d78268 GSEventRunModal + 217

       21  GraphicsServices                    0x02d7832d GSEventRun + 115

       22  UIKit                               0x0103e42e UIApplicationMain + 1160

       23  appTest                              0x00012919 main + 121

       24  appTest                              0x00012895 start + 53

)

terminate called throwing an exception

 

appTest[64158:fe03] -[UITableViewCell atestFun:]: unrecognized selector sent to instance 0x6bceb20

2012-06-08 17:09:14.813 appTest[64158:fe03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITableViewCell atestFun:]: unrecognized selector sent to instance 0x6bceb20'

*** Call stack at first throw:

(

       0   CoreFoundation                      0x028bcbe9 __exceptionPreprocess + 185

       1   libobjc.A.dylib                     0x02a115c2 objc_exception_throw + 47

       2   CoreFoundation                      0x028be6fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187

       3   CoreFoundation                      0x0282e366 ___forwarding___ + 966

       4   CoreFoundation                      0x0282df22 _CF_forwarding_prep_0 + 50

       5   Foundation                          0x00d996c1 _nsnote_callback + 145

       6   CoreFoundation                      0x02894f99 __CFXNotificationPost_old + 745

       7   CoreFoundation                      0x0281433a _CFXNotificationPostNotification + 186

       8   Foundation                          0x00d8f266 -[NSNotificationCenter postNotificationName:object:userInfo:] + 134

       9   Foundation                          0x00d9b5a9 -[NSNotificationCenter postNotificationName:object:] + 56

 

 

2012-06-09 10:14:39.823 appTest[65900:fe03] -[NSCFNumber atestFun:]: unrecognized selector sent to instance 0x6e639a0

2012-06-09 10:14:39.928 appTest[65900:fe03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFNumber atestFun:]: unrecognized selector sent to instance 0x6e639a0'

*** Call stack at first throw:

 

 

典型的野指针问题

 

指针乱指

 

指针互指

委托,代理模式就是采用的这种方法进行的实现

关注下指针互指的情况

 

C

 

@property(nonatomic, assign) id p;

 

void dealloc

{

          [p release];

          ...

}

 

 

----

A

 

C * c;

 

void dealloc

{

          [c release];

         

}

 

--

C dealloc 方法中不应该写[p release];

写了后,调用Adealloc, 执行到[c release] 又会调用C dealloc

又调用Adealloc 。。。

这样会出现循环调用,直到stack空间不足,程序崩溃

dealloc中测试发现 [p retainCount]  [c retainCount] 的值都是1

(gdb) po [m_delegate retainCount]

0x1 does not appear to point to a valid object.

(gdb) po [self retainCount]

0x1 does not appear to point to a valid object.

 

 

从这里可以看出,对于互指的指针(代理),需要注意其使用

 

同时,可以看出 self.p = nil; 这种写法的好处,这样写不仅符合美学上对称(使用release的话,并没有与之对应的alloc),

而且不用关注变量的属性(retain还是assign,

写成 self.p = nil;是没有问题的,如果是assign, 就不会去调用release

 

内存泄露

多释放一个对象,可能会造成崩溃(其他地方再使用的时候出现野指针问题)

相对于这种夺命顽症,内存泄露则是一个慢性病,它会在内存泄露积累到一定程度的时候表现出来。少释放也是不可以的。

对于频繁调用的函数,需要格外注意其内存释放问题。

 

常用控件

UIButton

UIView

UIScrollView

UITableView

在使用tableView的时候,可以不使用其重用机制来实现特定的功能

 

XMLJSON解析

在对复杂的结构进行解析的时候,可以采用责任链模式,对特定模块进行封装,这样结构会清晰直观。

 

 

猜你喜欢

转载自blog.csdn.net/aaajj/article/details/7933234