您的位置:首页 > 其它

某自称菜鸟的日常笔记(3)

2015-10-07 09:33 253 查看
iOS main函数 机器码 ,不懂汇编,哪里写错了,麻烦指出来

0x2730: pushl 0(将出错码入栈)0x2730:pushl0 ( 将出错码入栈)
0x2730: pushl 0 ( 将出错码入栈)

当异常发生时,如果控制单元没有自动地把一个硬件错误代码插入到栈中,相应的汇编语言片段会包含一条pushl $0指令,在栈中垫上一个空值,如果错误码已经被压入堆栈,则没有这条指令。然后,把异常处理函数的地址压进栈中;函数的名字由异常处理程序名与do_前缀组成

0x2732: movl %esp, %ebp

栈指址(低地址)%esp栈顶值赋给栈基址(高地址)%ebp栈底,设置 main函数的栈基址

0x2734: andl −16,它等价于andl-16, %esp
它等价于 andl 0xfffffff0,%esp,也就是说把%esp内的最后4位给抹掉,强制让%esp的值是16的倍数,GCC默认的堆栈是16字节对齐的,为了加快CPU的访问效率

0x2737: subl $16, %esp

%esp栈顶向下移动16个字节,给临时变量留出来

0x273a: movl 4(%ebp), %ebx

保存旧的栈基址,4(%ebp)等于 : (%ebp +4) ,%ebp + 4

是表示一个地址值,加上括号表示存储在该地址上的内容

0x273d: movl %ebx, (%esp)

复制对齐的指针 ,把%ebx的值写到栈顶,但不会使栈指针值发生变化

0x2740: leal 8(%ebp), %ecx

局部变量的地址直到程序运行才能被识别,必须用leal指令寻址。但leal的效率相对movl xxx要低得多 ,传送%ebp+8的地址写到%ecx寄存器

0x2743: movl %ecx, 4(%esp)

把%ecx的值写到%esp+4

0x2747: addl $1, %ebx

%ebx+1

0x274a: shll $2, %ebx

%ebx 左移2位

0x274d: addl %ecx, %ebx

%ebx+ %ecx

0x274f: movl %ebx, 8(%esp)

把%ebx值写到%esp+8

0x2753: movl (%ebx), %eax

把%ebx值写到%eax寄存器

0x2755: addl $4, %ebx

%ebx+4

0x2758: testl %eax, %eax

testl的执行会影响状态寄存器。%eax & %eax

如果al不为0,则testb %eax , %eax,标志位NZ为1

0x275a: jne 0x2753 ; start + 35

jne不等于时转移

0x275c: movl %ebx, 12(%esp)

把%ebx值写到%esp+12

0x2760: calll 0x27b0 ; main at main.m:14

calll 将当前的IP压栈后,转到标号处执行指令

调用0x27b0标示的程序

0x2765: movl %eax, (%esp)

把%eax值写到%esp

0x2768: calll 0xb2db6 ; symbol stub for: exit

调用0xb2db6标示的程序

0x276d: hlt

cpu暂停,等到有复位信号或中断信号输入再运行

0x276e: nop

空指令,就是让cpu等待一个周期,可能等待外设输入

0x276f: nop

//–

分析开发者指南源码 GIT地址 https://github.com/iimgal/StudyiOS

ContactViewController.h 头文件

复制代码

import

import

import

import “ContactViewController.h”

@implementation ContactViewController

//合成器

@synthesize label;

/**

手动初始化ViewController nibNameOrNil 直需要文件名,无需扩展即contact(.nib不需要)

**/

- (id)initWithNibName:(NSString )nibNameOrNil bundle:(NSBundle )nibBundleOrNil

{

self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

//初始化父类ViewController

if (self) {

// Custom initialization

}

return self; //跳出

}

/**

当内存不足时,释放不需要的内存,缓存,未显示的view等

**/

- (void)didReceiveMemoryWarning

{

// Releases the view if it doesn’t have a superview.

[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.


}

#pragma mark - View lifecycle

/*

// Implement loadView to create a view hierarchy programmatically, without using a nib.

- (void)loadView

{

}

*/

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.

/**

视图加载时调用

**/

- (void)viewDidLoad

{

// 增加Code按钮,可跳转至教学页面

//初始化一个新的按钮,使用指定的标题,样式,目标(自己还是其他view视图),出口方法。

UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@”Code” style:UIBarButtonItemStyleBordered target:self action:@selector(code)];

//设置按钮到右侧

self.navigationItem.rightBarButtonItem = item;

//初始化

[super viewDidLoad];

}

/**

当内存不足时,最大程度释放内存

**/

- (void)viewDidUnload

{

self.label = nil; //重置lable

[super viewDidUnload]; //释放内存

// Release any retained subviews of the main view.

// e.g. self.myOutlet = nil;

}

/**

是否支持iphone 旋转

**/

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

{

// Return YES for supported orientations

//系统默认不支持旋转功能

return (interfaceOrientation == UIInterfaceOrientationPortrait);

}

重点内容#pragma mark -

#pragma mark Show all contacts

// Called when users tap “Display Picker” in the application. Displays a list of contacts and allows users to select a contact from that list.

// The application only shows the phone, email, and birthdate information of the selected contact.

/**

查看联系人数据

1、先初始化系统通讯控件

2、设置需要显示的信息,手机等

3、用presentModalViewController 呈现

**/

-(void)showPeoplePickerController

{

// 查看联系人 系统的通讯录控件

ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];

picker.peoplePickerDelegate = self; //委托给自己

// Display only a person’s phone, email, and birthdate

/**
消息设置版
[picker setDisplayedProperties:[NSArray arrayWithObjects:[NSNumber numberWithInt:kABPersonPhoneProperty],
[NSNumber numberWithInt:kABPersonEmailProperty],
[NSNumber numberWithInt:kABPersonBirthdayProperty], nil]];

//属性版
picker.displayedProperties = NSArray arrayWithObjects:[NSNumber numberWithInt:kABPersonPhoneProperty],
[NSNumber numberWithInt:kABPersonEmailProperty],
[NSNumber numberWithInt:kABPersonBirthdayProperty], nil];
*/

//将手机,邮箱,生日数据压入数组
NSArray *displayedItems = [NSArray arrayWithObjects:[NSNumber numberWithInt:kABPersonPhoneProperty],
[NSNumber numberWithInt:kABPersonEmailProperty],
[NSNumber numberWithInt:kABPersonBirthdayProperty], nil];

//设置需要显示的数据
picker.displayedProperties = displayedItems;

// Show the picker
//显示数据 使用 presentModalViewController可创建新视图,可用于视图之间的切换
[self presentModalViewController:picker animated:YES];


}

#pragma mark Display and edit a person

// Called when users tap “Display and Edit Contact” in the application. Searches for a contact named “Appleseed” in

// in the address book. Displays and allows editing of all information associated with that contact if

// the search is successful. Shows an alert, otherwise.

/**

编辑地址薄数据

1、ABAddressBookCreate 得到地址薄

2、查找是否有张三数据

3、如果没有提示用户,有则进入编辑视图

**/

-(void)showPersonViewController

{

// 得到地址薄 iphone6.0不推荐使用

ABAddressBookRef addressBook = ABAddressBookCreate();

// 寻找名为“CC”的联系人

NSArray people = (__bridge NSArray )ABAddressBookCopyPeopleWithName(addressBook, CFSTR(“zhangsan”));

// Display “Appleseed” information if found in the address book

//如果有数据

if ((people != nil) && [people count])

{

//ABRecordRef 一个指向Core Foundation对象的通用指针

ABRecordRef person = (__bridge ABRecordRef)[people objectAtIndex:0];

ABPersonViewController *picker = [[ABPersonViewController alloc] init]; //初始化

picker.personViewDelegate = self;

picker.displayedPerson = person;

//精简版 picker.displayedPerson = (__bridge ABRecordRef)[people objectAtIndex:0];

// Allow users to edit the person’s information

picker.allowsEditing = YES;

//更新联系人数据到编辑视图

[self.navigationController pushViewController:picker animated:YES];

}

else //没有数据则给一些提示信息

{

// Show an alert if “Appleseed” is not in Contacts

//UIAlertView常用于应用界面信息警告提示

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@”Error”

message:@”Could not find 张三 in the Contacts application”

delegate:nil

cancelButtonTitle:@”Cancel”

otherButtonTitles:nil];

[alert show]; //弹出提示

}

CFRelease(addressBook); //释放


}

#pragma mark Create a new person

// Called when users tap “Create New Contact” in the application. Allows users to create a new contact.

/**

创建新的联系人

1、初始化系统的新增联系人控件

2、新建一个导航控制器

3、创建新视图

**/

-(void)showNewPersonViewController

{

// 初始化系统的新增联系人控件

ABNewPersonViewController *picker = [[ABNewPersonViewController alloc] init];

picker.newPersonViewDelegate = self;

//新建一个导航控制器
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:picker];
//创建新视图,可用于视图之间的切换
[self presentModalViewController:navigation animated:YES];


}

pragma mark Add data to an existing person

// Called when users tap “Edit Unknown Contact” in the application.

/**

当点击未知联系人

**/

-(void)showUnknownPersonViewController

{

// 打开联系人数据库 iphone6.0不推荐使用

ABRecordRef aContact = ABPersonCreate();

CFErrorRef anError = NULL;

//返回一个新的,空的,可变的多值属性
ABMultiValueRef email = ABMultiValueCreateMutable(kABMultiStringPropertyType);

//添加到多值属性的值及其对应的标签。
bool didAdd = ABMultiValueAddValueAndLabel(email, @"John-Appleseed@mac.com", kABOtherLabel, NULL);

if (didAdd == YES) //添加成功
{
//添加单个项的属性值,如邮箱. int32_t ABPropertyID
ABRecordSetValue(aContact, kABPersonEmailProperty, email, &anError);
if (anError == NULL)
{
//设置联系人数据
ABUnknownPersonViewController *picker = [[ABUnknownPersonViewController alloc] init];
picker.unknownPersonViewDelegate = self;
picker.displayedPerson = aContact;
picker.allowsAddingToAddressBook = YES;
picker.allowsActions = YES;
picker.alternateName = @"John Appleseed";
picker.title = @"John Appleseed";
picker.message = @"Company, Inc";

//创建新视图
[self.navigationController pushViewController:picker animated:YES];

}
else  //添加失败,给提示信息
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"Could not create unknown user"
delegate:nil
cancelButtonTitle:@"Cancel"
otherButtonTitles:nil];
[alert show];
}
}
CFRelease(email);//释放
CFRelease(aContact);//释放


}

#pragma mark ABPeoplePickerNavigationControllerDelegate methods

// Displays the information of a selected person

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker

shouldContinueAfterSelectingPerson:(ABRecordRef)person

{

self.label.text = [IIAddressBook getFullName:person];

//[self dismissModalViewControllerAnimated:YES];

//return NO;

return YES;

}

// Does not allow users to perform default actions such as dialing a phone number, when they select a person property.

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person

property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier

{

return NO;

}

// Dismisses the people picker and shows the application when users tap Cancel.

- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker;

{

[self dismissModalViewControllerAnimated:YES];

}

#pragma mark ABPersonViewControllerDelegate methods

// Does not allow users to perform default actions such as dialing a phone number, when they select a contact property.

- (BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person

property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue

{

return NO;

}

#pragma mark ABNewPersonViewControllerDelegate methods

// Dismisses the new-person view controller.

- (void)newPersonViewController:(ABNewPersonViewController *)newPersonViewController didCompleteWithNewPerson:(ABRecordRef)person

{

[self dismissModalViewControllerAnimated:YES];

}

#pragma mark ABUnknownPersonViewControllerDelegate methods

// Dismisses the picker when users are done creating a contact or adding the displayed person properties to an existing contact.

- (void)unknownPersonViewController:(ABUnknownPersonViewController *)unknownPersonView didResolveToPerson:(ABRecordRef)person

{

[self dismissModalViewControllerAnimated:YES];

}

// Does not allow users to perform default actions such as emailing a contact, when they select a contact property.

- (BOOL)unknownPersonViewController:(ABUnknownPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person

property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier

{

return NO;

}

// 跳转至教学页面

- (void)code

{

//初始化code一些提示数据 视图

CodeViewController *controller = [[CodeViewController alloc] initWithNibName:@”CodeViewController” bundle:nil];

NSString *name = [NSString stringWithUTF8String:object_getClassName(self)];

controller.className = name;

//精简版 controller.className = [NSString stringWithUTF8String:object_getClassName(self)];

[self.navigationController pushViewController:controller animated:YES];


}

@end

//–

知识重点:

1

AddressBookUI中提供了和联系人显示信息相关的一些Controller,有四个:

ABPeoplePickerNavigationController:显示整个通讯录并可以选择一个联系人的信息

ABPersonViewController:显示一个具体联系人的信息

ABNewPersonViewController:增加一个新的联系人

ABUnknownPersonViewController:完善一个联系人的信息

2

viewDidLoad其实没什么可混淆的,无论通过什么途径加载(Xcode或者IB,这里的加载属于实例化)完view后肯定会执行这个方法.

loadView需要分两种情况.当你通过Xcode实例化一个类的时候就需要自己在controller中实现这个方法.而在IB中实例化就不需要实现它.

initWithNibName这个方法是在controller的类在IB中创建,但是通过Xcode实例化controller的时候用的.

awakeFromNib是类在IB中被实例化调用.推荐使用viewDidLoad,因为viewDidLoad会被多次调用,而awakeFromNib只会当从nib文件中unarchive的时候才会被调用一次,awakeFromNib被调用时,viewDidLoad不会被调用

当.nib文件被加载的时候,会发送一个awakeFromNib的消息到.nib文件中的每个对象,每个对象都可以定义自己的awakeFromNib函数来响应这个消息,也就是说通过nib文件创建view对象来执行awakeFromNib

当view对象被加载到内存是就会执行viewDidLoad,所以不管通过nib文件还是代码的方式创建对象都会执行viewDidLoad

3.

UIBarButtonItem 工具栏按钮有3种主要的定制方法:1、在Interface builder中定制;2、setItems方法定制;3、addSubview方法定制。

UIBarButtonItem * clearnButton = [UIBarButtonItem alloc] initWithTitle:@”Code” style:UIBarButtonItemStyleBordered target:self action:@selector(code)]; 初始化

NSArray *buttonArray = [[NSArray alloc]initWithObjects:cleanButton,saveButton, nil];

self.navigationItem.rightBarButtonItems = buttonArray; 多按钮用法

4、

[super class] 先转换成 objc_msgSendSuper 的方法。构造 objc_super 的结构体

id objc_msgSendSuper(struct objc_super *super, SEL op, …)

struct objc_super {

id receiver;

Class superClass;

};

shouldAutorotateToInterfaceOrientation 自动旋转功能

5、

ABPeoplePickerNavigationController 系统的通讯录控件

ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];

picker.peoplePickerDelegate = self; //初始化

6、

__bridge只做类型转换,但是不修改对象(内存)管理权;

__bridge_transfer(也可以使用CFBridgingRelease)将Core Foundation的对象转换为Objective-C的对象,同时将对象(内存)的管理权交给ARC。

7、

__bridge_retained(也可以使用CFBridgingRetain)将Objective-C的对象转换为Core Foundation的对象,同时将对象(内存)的管理权交给我们,后续需要使用CFRelease或者相关方法来释放对象

8、

UIAlertView常用于应用界面信息警告提示

9、

ABRecordRef 一个指向Core Foundation对象的通用指针

ABRecordRef是某一条通讯录记录

ABMultiValueRef是通讯录中某一个可能有多个字段数值的记录

ABAddressBookRef 就是某个通讯录

ABRecordID是记录的id, int类型

10、

ABMultiValueCreateMutable 返回一个新的,空的,可变的多值属性

ABMultiValueAddValueAndLabel 添加到多值属性的值及其对应的标签

ABRecordSetValue(aContact, kABPersonEmailProperty, email, &anError); 添加单个项的属性值
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: