如果你无法获知一个字体文件的字体全名(如下图)

 

 

 

 

 



 
 
 
 

//

//  CustomFonts.h

//  StarBunkerRaiders

//

//  Created by willonboy zhang on 12-5-17.

//  Copyright (c) 2012 willonboy.tk. All rights reserved.

//  用下面的方法只需要知道字体文件名即可  但强烈建议直接使用[UIFont fontWithName:字体全名 size:size]方式!!! 不会造成内存问题

 

#define DEFAULT_FONT(x)                     [CustomFonts defaultFont:(x)]

 

 

#import <Foundation/Foundation.h>

 

@interface CustomFonts : NSObject

 

+ (UIFont *)defaultFont:(int)size;;

+ (UIFont *)loadCustomFont:(NSString *)fontFileName fontSize:(int)size;

 

@end
 
 
 
 
 
 
 
 
 
 
 

//

//  CustomFonts.m

//  StarBunkerRaiders

//

//  Created by willonboy zhang on 12-5-17.

//  Copyright (c) 2012 willonboy.tk. All rights reserved.

//

 

#import "CustomFonts.h"

 

@implementation CustomFonts

 

+ (UIFont *)defaultFont:(int)size;

{

    return [CustomFontsloadCustomFont:@"FZY3JW.TTF"fontSize:size];

//    return [CustomFonts loadCustomFont:@"方正准圆GBK+HandelGotDLig+Digifaw.ttf" fontSize:size];

//    return [CustomFonts loadCustomFont:@"悦黑常体.otf" fontSize:size];

    

}

 

+ (UIFont *)loadCustomFont:(NSString *)fontFileName fontSize:(int)size;

{

    NSString *fontPath = [[NSBundlemainBundlepathForResource:fontFileName ofType:[fontFileName pathExtension]];

    

    if (fontPath == nil

    {

         fontPath = [[NSBundlemainBundle] pathForResource:fontFileName ofType:nil];

    }

    

    if (fontPath == nil)

    {

        returnnil;

    }

    

    NSURL *url = [NSURLfileURLWithPath:fontPath];

    CGDataProviderRef fontDataProvider = CGDataProviderCreateWithURL((CFURLRef)url);

    

    if (fontDataProvider == NULL

    {

        returnnil;

    }   

    

    CGFontRef newFont = CGFontCreateWithDataProvider(fontDataProvider); 

    NSString *fontName = (NSString *)CGFontCopyFullName(newFont);

    UIFont *font = [UIFont fontWithName:fontName size:size];

    NSLog(@"fontname is %@", fontName);

        

    CFRelease(newFont);

    CFRelease(fontDataProvider);

    [fontName release];

    return font;

}

 

 

@end
 
 

ELF文件即可执行与可链接格式

On 2012/05/07, in C/C++, by willonboy

 

 
可执行和可链接格式 (英语:Executable and Linkable Format,缩写为ELF),常被称为ELF格式,在计算机科学中,是一种用于执行档、目的档、共享库和核心转储的标准文件格式。
1999年,被86open项目选为x86架构上的类Unix操作系统的二进制文件格式标准,用来取代COFF。因其可扩展性与灵活性,也可应用在其它处理器、计算机系统架构的操作系统上。
 
扩展名 沒有,.o,.so,.elf,.prx
开发者 Unix系统实验室
格式 二进制档案,执行档,目标代码,共享库,核心转储
 
文件格式
ELF文件有两种索引:程序头中记载了运行时所需的段,而段首地址表记载了二进制文件中段的首地址
ELF文件的组成:ELF header
程序头:描述段信息
Section头:链接与重定位需要的数据
程序头与Section头需要的数据.text .data
 
 
 
查看工具
readelf显示elf文件
objdump显示elf和object格式文件
 
 
 
 
 
ELF文件有两种索引:程序头中记载了运行时所需的,而段首地址表记载了二进制文件中的首地址
 
 
 
 
推荐:http://blog.csdn.net/lights_joy/article/category/452838
 
 
 
 
 
 
 
 
 
 
From:http://blog.csdn.net/longxin007/article/details/1880477
 

 

 

前言
如果普通编程不需要了解这些东西,如果想精确控制你的对象文件的格式或者你想查看一下文件对象里的内容以便作出某种判断,刚你可以看一下下面的工具:objdump, nm, ar。当然,本文不可能非常详细的说明它们的使用方法和功能。如果你觉得本文不够清楚,你可以使用:man. 我的计划只是想让更多的人了解这些工具,以后在今后 的编程过程中能有所帮助。

 

 

 

 

操作系统: Linux

开始

  1. 库文件操作命令:ar —-非常好的东东。。让你能查看函数库里的详细情况和用多个对象文件生成一个库文件。
    1. 经常用法:
      1. ar -t libname.a //显示所有对象文件(.o文件)的列表.例: # ar t libtest.a
        libtest1.o
        libtest2.o
      2. ar -rv libname.a  objfile1.o objfile2.o … objfilen.o  //把objfile1.o–objfilen.o打包成一个库文件
    2. ar 选项
      d:从库中删除模块。按模块原来的文件名指定要删除的模块。如果使用了任选项v则列出被删除的每个模块。
      m:该操作是在一个库中移动成员。当库中如果有若干模块有相同的符号定义(如函数定义),则成员的位置顺序很重要。如果没有指定任选项,任何指定的成员将移到库的最后。也可以使用'a','b',或'I'任选项移动到指定的位置。
      p:显示库中指定的成员到标准输出。如果指定任选项v,则在输出成员的内容前,将显示成员的名字。如果没有指定成员的名字,所有库中的文件将显示出来。
      q:快速追加。增加新模块到库的结尾处。并不检查是否需要替换。'a','b',或'I'任选项对此操作没有影响,模块总是追加的库的结尾处。如果使用了任选项v则列出每个模块。 这时,库的符号表没有更新,可以用'ar s'或ranlib来更新库的符号表索引。
      r:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。
      t:显示库的模块表清单。一般只显示模块名。
      x:从库中提取一个成员。如果不指定要提取的模块,则提取库中所有的模块。
        下面在看看可与操作选项结合使用的任选项:

       

       

       

       

      a:在库的一个已经存在的成员后面增加一个新的文件。如果使用任选项a,则应该为命令行中membername参数指定一个已经存在的成员名。
      b:在库的一个已经存在的成员前面增加一个新的文件。如果使用任选项b,则应该为命令行中membername参数指定一个已经存在的成员名。
      c:创建一个库。不管库是否存在,都将创建。
      f:在库中截短指定的名字。缺省情况下,文件名的长度是不受限制的,可以使用此参数将文件名截短,以保证与其它系统的兼容。
      i:在库的一个已经存在的成员前面增加一个新的文件。如果使用任选项i,则应该为命令行中membername参数指定一个已经存在的成员名(类似任选项b)。
      l:暂未使用
      N:与count参数一起使用,在库中有多个相同的文件名时指定提取或输出的个数。
      o:当提取成员时,保留成员的原始数据。如果不指定该任选项,则提取出的模块的时间将标为提取出的时间。
      P:进行文件名匹配时使用全路径名。ar在创建库时不能使用全路径名(这样的库文件不符合POSIX标准),但是有些工具可以。
      s:写入一个目标文件索引到库中,或者更新一个存在的目标文件索引。甚至对于没有任何变化的库也作该动作。对一个库做ar s等同于对该库做ranlib。
      S:不创建目标文件索引,这在创建较大的库时能加快时间。
      u:一般说来,命令ar r…插入所有列出的文件到库中,如果你只想插入列出文件中那些比库中同名文件新的文件,就可以使用该任选项。该任选项只用于r操作选项。
      v:该选项用来显示执行操作选项的附加信息。
      V:显示ar的版本.

  2. nm –列出目标文件(.o)的符号清单。。NND,太激动了。刚知道此命令时让我三天没睡好觉。我就使劲用了一把。
    1. 常用法:
      1. nm -s filename.a/filename.o/a.out  里边所有的符号列表一清二楚。例:
        # nm -s a.out
        080495b8 A __bss_start
        08048334 t call_gmon_start
        080495b8 b completed.5751
        080494b8 d __CTOR_END__
        080494b4 d __CTOR_LIST__
        080495ac D __data_start
        080495ac W data_start
        08048450 t __do_global_ctors_aux
        08048360 t __do_global_dtors_aux
        080495b0 D __dso_handle
        080494c0 d __DTOR_END__
        080494bc d __DTOR_LIST__
        080494c8 d _DYNAMIC
        080495b8 A _edata
        080495bc A _end
        0804847c T _fini
        08048498 R _fp_hw
        08048390 t frame_dummy
        080484b0 r __FRAME_END__
        08049594 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
        0804844c T __i686.get_pc_thunk.bx
        080482b8 T _init
        080494b4 a __init_array_end
        080494b4 a __init_array_start
        0804849c R _IO_stdin_used
        080494c4 d __JCR_END__
        080494c4 d __JCR_LIST__
                 w _Jv_RegisterClasses
        080483e0 T __libc_csu_fini
        080483f0 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.0
        080483b4 T main
        080495b4 d p.5749
                 U puts@@GLIBC_2.0
        08048310 T _start
    2. 选项/属性:
      -a或–debug-syms:显示调试符号。
      -B:等同于–format=bsd,用来兼容MIPS的nm。
      -C或–demangle:将低级符号名解码(demangle)成用户级名字。这样可以使得C++函数名具有可读性。
      -D或–dynamic:显示动态符号。该任选项仅对于动态目标(例如特定类型的共享库)有意义。
      -f format:使用format格式输出。format可以选取bsd、sysv或posix,该选项在GNU的nm中有用。默认为bsd。
      -g或–extern-only:仅显示外部符号。
      -n、-v或–numeric-sort:按符号对应地址的顺序排序,而非按符号名的字符顺序。
      -p或–no-sort:按目标文件中遇到的符号顺序显示,不排序。
      -P或–portability:使用POSIX.2标准输出格式代替默认的输出格式。等同于使用任选项-f posix。
      -s或–print-armap:当列出库中成员的符号时,包含索引。索引的内容包含:哪些模块包含哪些名字的映射。
      -r或–reverse-sort:反转排序的顺序(例如,升序变为降序)。
      –size-sort:按大小排列符号顺序。该大小是按照一个符号的值与它下一个符号的值进行计算的。
      -t radix或–radix=radix:使用radix进制显示符号值。radix只能为"d"表示十进制、"o"表示八进制或"x"表示十六进制。
      –target=bfdname:指定一个目标代码的格式,而非使用系统的默认格式。
      -u或–undefined-only:仅显示没有定义的符号(那些外部符号)。
      -l或–line-numbers:对每个符号,使用调试信息来试图找到文件名和行号。对于已定义的符号,查找符号地址的行号。对于未定义符号,查找指向符号重定位入口的行号。如果可以找到行号信息,显示在符号信息之后。
      -V或–version:显示nm的版本号。
      –help:显示nm的任选项。
  3. objdump  文件命令功能强的惊人。能实现上述两个命令(ar,nm)的很多功能。它主要是查看对象文件的内容信息。
    1. 常用法:
      1. objdump -h file<.o,.a,.out>//查看对象文件所有的节sections.例如:
        # objdump -h libtest1.o
        libtest1.o:     file format elf32-i386
        Sections:
        Idx Name          Size      VMA       LMA       File off  Algn
          0 .text         00000014  00000000  00000000  00000034  2**2
                          CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
          1 .data         00000000  00000000  00000000  00000048  2**2
                          CONTENTS, ALLOC, LOAD, DATA
          2 .bss          00000000  00000000  00000000  00000048  2**2
                          ALLOC
          3 .rodata       0000000e  00000000  00000000  00000048  2**0
                          CONTENTS, ALLOC, LOAD, READONLY, DATA
          4 .comment      0000001f  00000000  00000000  00000056  2**0
                          CONTENTS, READONLY
          5 .note.GNU-stack 00000000  00000000  00000000  00000075  2**0
                          CONTENTS, READONLY
      2. objdump -t 查看对象文件所有的符号列表,相当于 nm -s objfilename,如:
        # objdump -t libtest1.o

         

         

         

         

        libtest1.o:     file format elf32-i386

        SYMBOL TABLE:
        00000000 l    df *ABS*  00000000 libtest1.c
        00000000 l    d  .text  00000000 .text
        00000000 l    d  .data  00000000 .data
        00000000 l    d  .bss   00000000 .bss
        00000000 l    d  .rodata        00000000 .rodata
        00000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack
        00000000 l    d  .comment       00000000 .comment
        00000000 g     F .text  00000014 print_test1
        00000000         *UND*  00000000 puts

    2. 更多信息请查看选项:
      –archive-headers
      -a 显示档案库的成员信息,与 ar tv 类似

       

       

       

       

          objdump -a libpcap.a
          和 ar -tv libpcap.a 显示结果比较比较
          显然这个选项没有什么意思。

      –adjust-vma=offset
          When  dumping  information, first add offset to all
          the section addresses.  This is useful if the  sec-
          tion  addresses  do  not correspond  to the symbol
          table, which can happen when  putting  sections  at
          particular  addresses when using a format which can
          not represent section addresses, such as a.out.

      -b bfdname
      –target=bfdname
          指定目标码格式。这不是必须的,objdump能自动识别许多格式,
          比如:objdump -b oasys -m vax -h fu.o
          显示fu.o的头部摘要信息,明确指出该文件是Vax系统下用Oasys
          编译器生成的目标文件。objdump -i将给出这里可以指定的
          目标码格式列表

      –demangle
      -C 将底层的符号名解码成用户级名字,除了去掉所有开头
         的下划线之外,还使得C++函数名以可理解的方式显示出来。

      –debugging 
          显示调试信息。企图解析保存在文件中的调试信息并以C语言
          的语法显示出来。仅仅支持某些类型的调试信息。

      –disassemble
      -d 反汇编那些应该还有指令机器码的section

      –disassemble-all
      -D 与 -d 类似,但反汇编所有section

      –prefix-addresses
          反汇编的时候,显示每一行的完整地址。这是一种比较老的反汇编格式。
          显示效果并不理想,但可能会用到其中的某些显示,自己可以对比。

      –disassemble-zeroes
          一般反汇编输出将省略大块的零,该选项使得这些零块也被反汇编。

      -EB
      -EL
      –endian={big|little}
          这个选项将影响反汇编出来的指令。
          little-endian就是我们当年在dos下玩汇编的时候常说的高位在高地址,
          x86都是这种。

      –file-headers
      -f 显示objfile中每个文件的整体头部摘要信息。

      –section-headers
      –headers
      -h 显示目标文件各个section的头部摘要信息。

      –help 简短的帮助信息。

      –info
      -i 显示对于 -b 或者 -m 选项可用的架构和目标格式列表。

      –section=name
      -j name 仅仅显示指定section的信息

      –line-numbers
      -l 用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用
         使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求
         编译时使用了-g之类的调试编译选项。

      –architecture=machine
      -m machine
          指定反汇编目标文件时使用的架构,当待反汇编文件本身没有描述
          架构信息的时候(比如S-records),这个选项很有用。可以用-i选项
          列出这里能够指定的架构

      –reloc
      -r 显示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反汇
         编后的格式显示出来。

      –dynamic-reloc
      -R 显示文件的动态重定位入口,仅仅对于动态目标文件有意义,比如某些
         共享库。

      –full-contents
      -s 显示指定section的完整内容。

          objdump –section=.text -s inet.o | more

      –source
      -S 尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,
         效果比较明显。隐含了-d参数。

      –show-raw-insn
          反汇编的时候,显示每条汇编指令对应的机器码,除非指定了
          –prefix-addresses,这将是缺省选项。

      –no-show-raw-insn
          反汇编时,不显示汇编指令的机器码,这是指定 –prefix-addresses
          选项时的缺省设置。

      –stabs
          Display the contents of the .stab, .stab.index, and
          .stab.excl sections from an ELF file.  This is only
          useful  on  systems  (such as Solaris 2.0) in which
          .stab debugging symbol-table entries are carried in
          an ELF section.  In most other file formats, debug-
          ging  symbol-table  entries  are interleaved  with
          linkage symbols, and are visible in the –syms output.

      –start-address=address
          从指定地址开始显示数据,该选项影响-d、-r和-s选项的输出。

      –stop-address=address
          显示数据直到指定地址为止,该选项影响-d、-r和-s选项的输出。

      –syms
      -t 显示文件的符号表入口。类似于nm -s提供的信息

      –dynamic-syms
      -T 显示文件的动态符号表入口,仅仅对动态目标文件有意义,比如某些
         共享库。它显示的信息类似于 nm -D|–dynamic 显示的信息。

      –version 版本信息

          objdump –version

      –all-headers
      -x 显示所有可用的头信息,包括符号表、重定位入口。-x 等价于
         -a -f -h -r -t 同时指定。

          objdump -x inet.o

 
 
 
 
 
 
objdump的使用方法
From:http://hi.baidu.com/gzxb/blog/item/795738cee520663ab700c8d1.html
 
概述:

 

 

     objdump有点象那个快速查看之流的工具,就是

     以一种可阅读的格式让你更多地了解二进制文件

     可能带有的附加信息。对于一般只想让自己程序

     跑起来的程序员,这个命令没有更多意义,对于

     想进一步了解系统的程序员,应该掌握这种工具,

     至少你可以自己写写shellcode了,或者看看人家

     给的exploit中的shellcode是什么东西。

 

目录:

 

     ★ 测试练习前的准备工作

     ★ Redhat 6.0 objdump命令的man手册

     ★ objdump应用举例(待增加)

     ★ 相关命令

 

★ 测试练习前的准备工作

 

cp /usr/lib/libpcap.a /home/scz/src

nm -s libpcap.a | more

ar tv libpcap.a

ar xv libpcap.a inet.o

nm -s inet.o

 

关于nm -s的显示请自己man nm查看

 

★ Redhat 6.0 objdump命令的man手册

 

objdump – 显示二进制文件信息

 

objdump

       [-a] [-b bfdname |

       --target=bfdname] [-C] [--debugging]

       [-d] [-D]

       [--disassemble-zeroes]

       [-EB|-EL|--endian={big|little}] [-f]

       [-h] [-i|--info]

       [-j section | --section=section]

       [-l] [-m machine ] [--prefix-addresses]

       [-r] [-R]

       [-s|--full-contents] [-S|--source]

       [--[no-]show-raw-insn] [--stabs] [-t]

       [-T] [-x]

       [--start-address=address] [--stop-address=address]

       [--adjust-vma=offset] [--version] [--help]

       objfile…

 

–archive-headers

-a 显示档案库的成员信息,与 ar tv 类似

 

     objdump -a libpcap.a

     和 ar -tv libpcap.a 显示结果比较比较

     显然这个选项没有什么意思。

 

–adjust-vma=offset

     When   dumping   information, first add offset to all

     the section addresses.   This is useful if the   sec-

     tion   addresses   do   not correspond   to the symbol

     table, which can happen when   putting   sections   at

     particular   addresses when using a format which can

     not represent section addresses, such as a.out.

 

-b bfdname

–target=bfdname

     指定目标码格式。这不是必须的,objdump能自动识别许多格式,

     比如:objdump -b oasys -m vax -h fu.o

     显示fu.o的头部摘要信息,明确指出该文件是Vax系统下用Oasys

     编译器生成的目标文件。objdump -i将给出这里可以指定的

     目标码格式列表

 

–demangle

-C 将底层的符号名解码成用户级名字,除了去掉所有开头

    的下划线之外,还使得C++函数名以可理解的方式显示出来。

 

–debugging 

     显示调试信息。企图解析保存在文件中的调试信息并以C语言

     的语法显示出来。仅仅支持某些类型的调试信息。

 

–disassemble

-d 反汇编那些应该还有指令机器码的section

 

–disassemble-all

-D 与 -d 类似,但反汇编所有section

 

–prefix-addresses

     反汇编的时候,显示每一行的完整地址。这是一种比较老的反汇编格式。

     显示效果并不理想,但可能会用到其中的某些显示,自己可以对比。

 

–disassemble-zeroes

     一般反汇编输出将省略大块的零,该选项使得这些零块也被反汇编。

 

-EB

-EL

–endian={big|little}

     这个选项将影响反汇编出来的指令。

     little-endian就是我们当年在dos下玩汇编的时候常说的高位在高地址,

     x86都是这种。

 

–file-headers

-f 显示objfile中每个文件的整体头部摘要信息。

 

–section-headers

–headers

-h 显示目标文件各个section的头部摘要信息。

 

–help 简短的帮助信息。

 

–info

-i 显示对于 -b 或者 -m 选项可用的架构和目标格式列表。

 

–section=name

-j name 仅仅显示指定section的信息

 

–line-numbers

-l 用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用

    使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求

    编译时使用了-g之类的调试编译选项。

 

–architecture=machine

-m machine

     指定反汇编目标文件时使用的架构,当待反汇编文件本身没有描述

     架构信息的时候(比如S-records),这个选项很有用。可以用-i选项

     列出这里能够指定的架构

 

–reloc

-r 显示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反汇

    编后的格式显示出来。

 

–dynamic-reloc

-R 显示文件的动态重定位入口,仅仅对于动态目标文件有意义,比如某些

    共享库。

 

–full-contents

-s 显示指定section的完整内容。

 

     objdump –section=.text -s inet.o | more

 

–source

-S 尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,

    效果比较明显。隐含了-d参数。

 

–show-raw-insn

     反汇编的时候,显示每条汇编指令对应的机器码,除非指定了

     –prefix-addresses,这将是缺省选项。

 

–no-show-raw-insn

     反汇编时,不显示汇编指令的机器码,这是指定 –prefix-addresses

     选项时的缺省设置。

 

–stabs

     Display the contents of the .stab, .stab.index, and

     .stab.excl sections from an ELF file.   This is only

     useful   on   systems   (such as Solaris 2.0) in which

     .stab debugging symbol-table entries are carried in

     an ELF section.   In most other file formats, debug-

     ging   symbol-table   entries   are interleaved   with

     linkage symbols, and are visible in the –syms output.

 

–start-address=address

     从指定地址开始显示数据,该选项影响-d、-r和-s选项的输出。

 

–stop-address=address

     显示数据直到指定地址为止,该选项影响-d、-r和-s选项的输出。

 

–syms

-t 显示文件的符号表入口。类似于nm -s提供的信息

 

–dynamic-syms

-T 显示文件的动态符号表入口,仅仅对动态目标文件有意义,比如某些

    共享库。它显示的信息类似于 nm -D|–dynamic 显示的信息。

 

–version 版本信息

 

     objdump –version

 

–all-headers

-x 显示所有可用的头信息,包括符号表、重定位入口。-x 等价于

    -a -f -h -r -t 同时指定。

 

     objdump -x inet.o

 

参看 nm(1)

 

★ objdump应用举例(待增加)

 

/*

g++ -g -Wstrict-prototypes -Wall -Wunused -o objtest objtest.c

*/

#include 

#include 

int main ( int argc, char * argv[] )

{

     execl( "/bin/sh", "/bin/sh", "-i", 0 );

     return 0;

}

 

g++ -g -Wstrict-prototypes -Wall -Wunused -o objtest objtest.c

objdump -j .text -Sl objtest | more

/main(查找)

 

08048750:

main():

/home/scz/src/objtest.c:7

*/

#include 

#include 

int main ( int argc, char * argv[] )

{

8048750:        55                       pushl   %ebp

8048751:        89 e5                    movl    %esp,%ebp

/home/scz/src/objtest.c:8

         execl( "/bin/sh", "/bin/sh", "-i", 0 );

8048753:        6a 00                    pushl   $0×0

8048755:        68 d0 87 04 08           pushl   $0x80487d0

804875a:        68 d3 87 04 08           pushl   $0x80487d3

804875f:        68 d3 87 04 08           pushl   $0x80487d3

8048764:        e8 db fe ff ff           call    8048644 <_init+0×40>

8048769:        83 c4 10                 addl    $0×10,%esp

/home/scz/src/objtest.c:9

         return 0;

804876c:        31 c0                    xorl    %eax,%eax

804876e:        eb 04                    jmp     8048774 

8048770:        31 c0                    xorl    %eax,%eax

8048772:        eb 00                    jmp     8048774 

/home/scz/src/objtest.c:10

}

8048774:        c9                       leave  

8048775:        c3                       ret    

8048776:        90                       nop 

 

如果说上面还不够清楚,可以用下面的命令辅助一下:

 

objdump -j .text -Sl objtest –prefix-addresses | more

objdump -j .text -Dl objtest | more

 

去掉调试编译选项重新编译

g++ -O3 -o objtest objtest.c

objdump -j .text -S objtest | more

 

08048778:

main():

8048778:        55                       pushl   %ebp

8048779:        89 e5                    movl    %esp,%ebp

804877b:        6a 00                    pushl   $0×0

804877d:        68 f0 87 04 08           pushl   $0x80487f0

8048782:        68 f3 87 04 08           pushl   $0x80487f3

8048787:        68 f3 87 04 08           pushl   $0x80487f3

804878c:        e8 db fe ff ff           call    804866c <_init+0×40>

8048791:        31 c0                    xorl    %eax,%eax

8048793:        c9                       leave  

8048794:        c3                       ret    

8048795:        90                       nop

 

与前面-g编译后的二进制代码比较一下,有不少区别。

 
 
 
 
 
 

[c/c++] objdump反汇编

一个挺好用的反汇编方法:

objdump -j .text -Sl objtest | more

-S 尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,

   效果比较明显。隐含了-d参数。

-l 用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用

  使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求

  编译时使用了-g之类的调试编译选项。

-j name 仅仅显示指定section的信息


同时发现objdump这个指令功能强大,下面是几个我认为常用的option:

objdump  -x  obj  以某种分类信息的形式把目标文档的数据组织(被分为几大块)输出    

objdump  -t  obj  输出目标文档的符号表

objdump  -h  obj  输出目标文档的section概括

 

 

 

 

 

 

 

 

 

 

Tagged with:  

有时需要在控制台或其他地方用到Finder中某个文件的路径, 获取路径的方法有点怪, 那就是先选中指定的文件然后copy它 ( comd+c ),  然后在Terminal中粘贴或在文本编辑器中粘贴即可 

Tagged with:  

UITextField的UIControl用法

On 2012/04/27, in iOS控件, by willonboy

有时候需要作个如下图的的输入密码页面, 每个框中只输入一个字母, 如果你只用了UITextFieldDelegate来作是不是非常难? 

其实UITextField也是UIControl的子类 , 并且UIControlEvents中明确的提供了几个专门针对UITextField的枚举值

{

 

UIControlEventEditingDidBegin     

UIControlEventEditingChanged      

UIControlEventEditingDidEnd       

UIControlEventEditingDidEndOnExit 

 

UIControlEventAllEditingEvents

}

 

 

 

 

 

 

 

 

 

 

 

//

//  PasswordInputMainView.h

//  

//

//  Created by willonboy zhang on 12-4-26.

//  Copyright (c) 2012 willonboy.tk. All rights reserved.

//

 

#import <UIKit/UIKit.h>

#import "Constant.h"

 

@protocol PasswordInputMainView <NSObject>

 

- (void)inputPwdComplete:(NSString *) pwd sender:(id)_sender;

 

@end

 

@interface PasswordInputMainView : UIView<UITextFieldDelegate>

{

    int             _currentTxtFieldIndex;

    NSMutableString *_passwordStr;

    

    UIImageView     *_topNavImgView;

    UIButton        *_backBtn;

    UILabel         *_titleLabel;

}

 

@property(nonatomic, readonly)UITextField *passFirstTxtField;

@property(nonatomic, readonly)UITextField *passSecondTxtField;

@property(nonatomic, readonly)UITextField *passThirdTxtField;

@property(nonatomic, readonly)UITextField *passForthTxtField;

@property(nonatomic, readonly)UILabel     *tipsMsgLabel;

@property(nonatomic, retain) NSString *tipsMsg;

@property(nonatomic, assign) id<PasswordInputMainView> delegate; 

 

 

@end

 
 
 
 
 
 
 
 
 
 
 
 
 

//

//  PasswordInputMainView.m

//  

//

//  Created by willonboy zhang on 12-4-26.

//  Copyright (c) 2012 willonboy.tk. All rights reserved.

//

 

#import "PasswordInputMainView.h"

 

@interface PasswordInputMainView()

 

- (void)initCustomView;

 

@end

 

 

 

 

 

@implementation PasswordInputMainView

@synthesize passFirstTxtField  = _passFirstTxtField ;

@synthesize passSecondTxtField = _passSecondTxtField;

@synthesize passThirdTxtField  = _passThirdTxtField ;

@synthesize passForthTxtField  = _passForthTxtField ;

@synthesize tipsMsgLabel       = _tipsMsgLabel;

@synthesize tipsMsg = _tipsMsg;

@synthesize delegate;

 

 

- (id)initWithFrame:(CGRect)frame

{

    self = [super initWithFrame:frame];

    if (self

    {

        _currentTxtFieldIndex = 0;

        _passwordStr = [[NSMutableString alloc] init];

    }

    return self;

}

 

- (void)dealloc 

{

    [_passFirstTxtField release];

    [_passSecondTxtField release];

    [_passThirdTxtField release];

    [_passForthTxtField release];

    [_tipsMsgLabel release];

    [super dealloc];

}

 

- (void)layoutSubviews

{

    [super layoutSubviews];

    [self initCustomView];

}

 

- (void)initCustomView

{

    

    if (_topNavImgView == nil)

    {

        _topNavImgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 45)];

        _topNavImgView.image = [UIImage imageNamed:@"topnavimg.png"];

        _topNavImgView.userInteractionEnabled = YES;

        [self addSubview:_topNavImgView];

        [_topNavImgView release];

    }

    

    if (_titleLabel == nil

    {

        _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 5, 320, 35)];

        _titleLabel.text = @"设置密码";

        _titleLabel.textColor = [UIColor whiteColor];

        _titleLabel.textAlignment = UITextAlignmentCenter;

        _titleLabel.font = [UIFont fontWithName:FONT_DFPS size:20.0f];

        _titleLabel.backgroundColor = [UIColor clearColor];

        [self addSubview:_titleLabel];

        [_titleLabel release];

    }

 

    

    if (_backBtn == nil)

    {

        _backBtn = [UIButton buttonWithType:UIButtonTypeCustom];

        _backBtn.frame = CGRectMake(0, 0, 40, 37);

        [_backBtn setImage:[UIImage imageNamed:@"backbtnimg.png"] forState:UIControlStateNormal];

        [_backBtn setImage:[UIImage imageNamed:@"backbtnimgh.png"] forState:UIControlStateHighlighted];

        [_backBtn addTarget:self action:@selector(dismissModalView) forControlEvents:UIControlEventTouchUpInside];

        [self addSubview:_backBtn];

        

    }

        

    if (_tipsMsgLabel == nil

    {

        _tipsMsgLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 60, 220, 20)];

        _tipsMsgLabel.textAlignment = UITextAlignmentCenter;

        _tipsMsgLabel.font = [UIFont fontWithName:FONT_DFPS size:17.0f];

        _tipsMsgLabel.textColor = [UIColor blackColor];

        [self addSubview: _tipsMsgLabel];

    }

    _tipsMsgLabel.text = _tipsMsg;

    [_tipsMsgLabel setNeedsLayout];

    

    if (_passFirstTxtField == nil

    {

        _passFirstTxtField  = [[UITextField alloc] initWithFrame:CGRectMake(24, 100, 50, 40)];

        _passFirstTxtField.textAlignment  = UITextAlignmentCenter;

        _passFirstTxtField.borderStyle  = UITextBorderStyleBezel

        _passFirstTxtField.keyboardType  = UIKeyboardTypeNumberPad;  

        _passFirstTxtField.secureTextEntry  = YES;      

        _passFirstTxtField.userInteractionEnabled  = YES;

        _passFirstTxtField.tag = 101;

        _passFirstTxtField.delegate  = self;

        [_passFirstTxtField addTarget:self action:@selector(endInputPwd:) forControlEvents:UIControlEventEditingChanged];

        [self addSubview:_passFirstTxtField];

    }

    

    if (_passSecondTxtField == nil

    {

        _passSecondTxtField  = [[UITextField alloc] initWithFrame:CGRectMake(98, 100, 50, 40)];

        _passSecondTxtField.textAlignment  = UITextAlignmentCenter;

        _passSecondTxtField.borderStyle  = UITextBorderStyleBezel

        _passSecondTxtField.keyboardType  = UIKeyboardTypeNumberPad;  

        _passSecondTxtField.secureTextEntry  = YES;      

        _passSecondTxtField.userInteractionEnabled  = NO;

        _passSecondTxtField.tag = 102;

        _passSecondTxtField.delegate  = self;

        [_passSecondTxtField addTarget:self action:@selector(endInputPwd:) forControlEvents:UIControlEventEditingChanged];

        [self addSubview:_passSecondTxtField];

    }

    

    if (_passThirdTxtField == nil

    {

        _passThirdTxtField  = [[UITextField alloc] initWithFrame:CGRectMake(172, 100, 50, 40)];

        _passThirdTxtField.textAlignment  = UITextAlignmentCenter;

        _passThirdTxtField.borderStyle  = UITextBorderStyleBezel

        _passThirdTxtField.keyboardType  = UIKeyboardTypeNumberPad;  

        _passThirdTxtField.secureTextEntry  = YES;      

        _passThirdTxtField.userInteractionEnabled  = NO;

        _passThirdTxtField.tag = 103;

        _passThirdTxtField.delegate  = self;

        [_passThirdTxtField addTarget:self action:@selector(endInputPwd:) forControlEvents:UIControlEventEditingChanged];

        [self addSubview:_passThirdTxtField];

    }

    

    if (_passForthTxtField == nil

    {

        _passForthTxtField  = [[UITextField alloc] initWithFrame:CGRectMake(246, 100, 50, 40)];

        _passForthTxtField.textAlignment  = UITextAlignmentCenter;

        _passForthTxtField.borderStyle  = UITextBorderStyleBezel

        _passForthTxtField.keyboardType  = UIKeyboardTypeNumberPad;  

        _passForthTxtField.secureTextEntry  = YES;      

        _passForthTxtField.userInteractionEnabled  = NO;

        _passForthTxtField.tag = 104;

        _passForthTxtField.delegate  = self;

        [_passForthTxtField addTarget:self action:@selector(endInputPwd:) forControlEvents:UIControlEventEditingChanged];

        [self addSubview:_passForthTxtField];

    }  

    

    [_passFirstTxtField becomeFirstResponder];

    

    

    

}

 

 

- (void)dismissModalView

{

    [(UIViewController *)self.delegate dismissModalViewControllerAnimated:YES];

}

 

 

#pragma mark – UITextFieldDelegate

 

- (void)textFieldDidBeginEditing:(UITextField *)textField

{

}

 

- (void)textFieldDidEndEditing:(UITextField *)textField

{

    if (textField && textField.text && textField.text.length > 0)

    {

        [_passwordStr appendString:textField.text];

    }

    

}

 

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

{

    if(textField.text.length == 1)

    {

        return NO;

    }

    return YES;

}

 

 

- (void)endInputPwd:(id) sender

{

    UITextField *txtField = (UITextField *)sender;

    

    switch (txtField.tag

    { 

        case 101:

            _passFirstTxtField.userInteractionEnabled = NO;

            _passSecondTxtField.userInteractionEnabled = YES;

            [_passSecondTxtField becomeFirstResponder];

            break;

        case 102:

            _passSecondTxtField.userInteractionEnabled = NO;

            _passThirdTxtField.userInteractionEnabled = YES;

            [_passThirdTxtField becomeFirstResponder];

            break;

        case 103:

            _passThirdTxtField.userInteractionEnabled = NO;

            _passForthTxtField.userInteractionEnabled = YES;

            [_passForthTxtField becomeFirstResponder];

            break;

        case 104:

            _passForthTxtField.userInteractionEnabled = NO;

            NSLog(@"输入完成 result is %@", _passwordStr);

            if (self.delegate && [self.delegate respondsToSelector:@selector(inputPwdComplete: sender:)]) 

            {

                [self.delegate inputPwdComplete:[_passwordStr description] sender:self];

            }

            break;

        default:

            break;

    }

}

 

 

@end

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Tagged with:  

我用CoreText绘制富文本时出现了行间距不等, 和这里出现的问题一模一样

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

最终在http://www.cocoanetics.com/2012/02/radar-coretext-line-spacing-bug/

找到了DTCoreText库

 

 

 

Radar: “CoreText Line Spacing Bug”

I finally got around to report an annoying bug in CoreText that has been bugging us in DTCoreText until I wrote a method to correct line origins as a workaround. rdar://10810114

The annoying thing about this bug is that it adds visual noise to otherwise pristinely rendered text. Especially on larger font sizes you see that additional space appears before each CTLine that ends with a paragraph break (\n).

UPDATE: This is a duplicate of rdar://9931615.

 

 

CoreText Line Spacing Bug

Summary

CoreText inserts too much space before any line that ends with a \n. This extra space depends on the font and font size. On large print this causes visual noise by not being uniform.

Steps to Reproduce

Create a CTFrame from a CTFrameSetter with a string that is long enough to wrap and that contains paragraph breaks. Use a non-UI font, like for example AriaMT.

Expected Results

Line origins should be spaced by exactly the same distance for identical text and identical attributes.

Actual Results

Each line that ends with a paragraph break is shifted down. With the system UI font, size 54 baselines are spaced exactly 64 pixels apart. With ArialMT, size 54, baseline spacing differs between 62 and 65.

Regression

This has been a bug since before iOS 4.3.

Notes

This does not occur with all fonts, Using a system font the spacing is precisely correct. I have attached a project to demonstrate the issue. See TextView.m.

It appears that the text metrics for an (invisible) paragraph glyph are miscalculated. Since the glyph is not visible you’d expect neither and ascender nor descender value. But instead the descender is too large. If you walk through the entire line and get the maximum ascenders and descenders the value is correct if you omit the \n in this calculation.

In short: A trailing \n messes up the font metrics for the entire CTLine.

Attachment: CoreTextLineOrigins Demo Project

 

 

 

 

DTCoreText Q&A: http://www.cocoanetics.com/2011/08/nsattributedstringhtml-qa/

 

Tagged with:  

最近下了个ARC工程的代码, 关于Core Text的第三方库, 里面看到了这个关键字, google了下才知道这里由于ARC不能管理Core Foundation Object的生命周期才引入的一个操作关键字

 

原文在这里:http://stackoverflow.com/questions/7036350/arc-and-bridged-cast

 

主要内容如下:

 

With ARC, I can no longer cast CGColorRef to id. I learned that I need to do a bridged cast. According clang docs:
 
A bridged cast is a C-style cast annotated with one of three keywords:
 
(__bridge T) op casts the operand to the destination type T. If T is a retainable object pointer type, then op must have a non-retainable pointer type. If T is a non-retainable pointer type, then op must have a retainable object pointer type. Otherwise the cast is ill-formed. There is no transfer of ownership, and ARC inserts no retain operations.
 
(__bridge_retained T) op casts the operand, which must have retainable object pointer type, to the destination type, which must be a non-retainable pointer type. ARC retains the value, subject to the usual optimizations on local values, and the recipient is responsible for balancing that +1.
 
(__bridge_transfer T) op casts the operand, which must have non-retainable pointer type, to the destination type, which must be a retainable object pointer type. ARC will release the value at the end of the enclosing full-expression, subject to the usual optimizations on local values.
 
These casts are required in order to transfer objects in and out of ARC control; see the rationale in the section on conversion of retainable object pointers.
 
Using a __bridge_retained or __bridge_transfer cast purely to convince ARC to emit an unbalanced retain or release, respectively, is poor form.
 
In what kind of situations would I use each?
 
For example, CAGradientLayer has a colors property which accepts an array of CGColorRefs. My guess is that I should use __brige here, but exactly why I should (or should not) is unclear.
 
 
Answer:
 
I agree that the description is confusing. Since I just grasped them, I'll try to summarize:
 
(__bridge_transfer <NSType>) op or alternatively CFBridgingRelease(op) is used to consume a retain-count of an CFObject while transfering it over to ARC. This could also be represented by id someObj = (__bridge <NSType>) op; CFRelease(op);
 
(__bridge_retained <CFType>) op or alternatively CFBridgingRetain(op) is used to hand an NSObject over to CF-Land while giving it a +1 retain count. You should handle an CFTypeRef you create this way the same as you would e.g. handle a result of CFStringCreateCopy(). This could also be represented by CFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;
 
__bridge just casts between pointer-land and Objective-C Object Land. If you have no inclination to use the converions above, use this one.
 
Maybe this is helpful. I myself prefer the CFBridging… macros quite a bit over the plain casts.

 

 

 

 

 

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

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

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

 

PS:  ARC is supported in Xcode 4.2 for Mac OS X v10.6 and v10.7 (64-bit applications) and for iOS 4 and iOS 5. Weak references are not supported in Mac OS X v10.6 and iOS 4. There is no ARC support in Xcode 4.1 and earlier.

 

参考文章:

http://www.yifeiyang.net/development-of-the-iphone-simply-6/

https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

 

 

 

 

 

Managing Toll-Free Bridging

In many Cocoa applications, you need to use Core Foundation-style objects, whether from the Core Foundation framework itself (such as CFArrayRef or CFMutableDictionaryRef) or from frameworks that adopt Core Foundation conventions such as Core Graphics (you might use types like CGColorSpaceRef and CGGradientRef).

The compiler does not automatically manage the lifetimes of Core Foundation objects; you must call CFRetain and CFRelease (or the corresponding type-specific variants) as dictated by the Core Foundation memory management rules (see Memory Management Programming Guide for Core Foundation).

If you cast between Objective-C and Core Foundation-style objects, you need to tell the compiler about the ownership semantics of the object using either a cast (defined in objc/runtime.h) or a Core Foundation-style macro (defined in NSObject.h):

  • __bridge transfers a pointer between Objective-C and Core Foundation with no transfer of ownership.

  • __bridge_retained or CFBridgingRetain casts an Objective-C pointer to a Core Foundation pointer and also transfers ownership to you.

    You are responsible for calling CFRelease or a related function to relinquish ownership of the object.

  • __bridge_transfer or CFBridgingRelease moves a non-Objective-C pointer to Objective-C and also transfers ownership to ARC.

    ARC is responsible for relinquishing ownership of the object.

For example, if you had code like this:

- (void)logFirstNameOfPerson:(ABRecordRef)person {
 
    NSString *name = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
    NSLog(@"Person's first name: %@", name);
    [name release];
}

you could replace it with:

- (void)logFirstNameOfPerson:(ABRecordRef)person {
 
    NSString *name = (NSString *)CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
    NSLog(@"Person's first name: %@", name);
}

The Compiler Handles CF Objects Returned From Cocoa Methods

The compiler understands Objective-C methods that return Core Foundation types follow the historical Cocoa naming conventions (see Advanced Memory Management Programming Guide). For example, the compiler knows that, in iOS, the CGColor returned by the CGColor method of UIColor is not owned. You must still use an appropriate type cast, as illustrated by this example:

NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]];
[colors addObject:(id)[[UIColor lightGrayColor] CGColor]];

Cast Function Parameters Using Ownership Keywords

When you cast between Objective-C and Core Foundation objects in function calls, you need to tell the compiler about the ownership semantics of the passed object. The ownership rules for Core Foundation objects are those specified in the Core Foundation memory management rules (see Memory Management Programming Guide for Core Foundation); rules for Objective-C objects are specified in Advanced Memory Management Programming Guide.

In the following code fragment, the array passed to the CGGradientCreateWithColors function requires an appropriate cast. Ownership of the object returned by arrayWithObjects: is not passed to the function, thus the cast is __bridge.

NSArray *colors = <#An array of colors#>;
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);

The code fragment is shown in context in the following method implementation. Notice also the use of Core Foundation memory management functions where dictated by the Core Foundation memory management rules.

- (void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
    CGFloat locations[2] = {0.0, 1.0};
    NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]];
    [colors addObject:(id)[[UIColor lightGrayColor] CGColor]];
    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);
    CGColorSpaceRelease(colorSpace);  // Release owned Core Foundation object.
    CGPoint startPoint = CGPointMake(0.0, 0.0);
    CGPoint endPoint = CGPointMake(CGRectGetMaxX(self.bounds), CGRectGetMaxY(self.bounds));
    CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint,
                                kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
    CGGradientRelease(gradient);  // Release owned Core Foundation object.
}

 

 

 

Tagged with:  

 

#cd ~/Desktop
pwd
ls -all
echo "Start Delete======================================================"
find . -type f -name Thumbs.db -delete
find . -type f -name .DS_Store -delete
find . -type d -name '.svn' | xargs rm -rf
echo "End Delete  ======================================================"
ls -all
 
 
 
将上面的语句保存成文件(最好不要有后缀名), 然后chmod 755, 然后你就可以在Terminal中执行该批处理文件了



//

//  EntryPoint.h

//  MacAppEntryPointFunction

//

//  Created by willonboy zhang on 12-4-10.

//  Copyright (c) 2012 willonboy.tk. All rights reserved.

//

 

#import <Foundation/Foundation.h>

 

@interface EntryPoint : NSObject

 

@end
 
 
//=========================================================================================
 
 
 
 

//

//  EntryPoint.m

//  MacAppEntryPointFunction

//

//  Created by willonboy zhang on 12-4-10.

//  Copyright (c) 2012 willonboy.tk. All rights reserved.

//

 

#import "EntryPoint.h"

 

@implementation EntryPoint

 

 

    //实际上Mac 下的进程是先从进程文件中查找一个 " +(void)load " 方法然后再执行main函数

+(void)load

{

    NSLog(@"我比main函数还要先执行");

}

 

 

@end
 
 
 
 
 
 
//=========================================================================================
 
 
 
 
 
 
 
 
 

//

//  main.m

//  MacAppEntryPointFunction

//

//  Created by willonboy zhang on 12-4-10.

//  Copyright (c) 2012 willonboy.tk. All rights reserved.

//

 

#import <UIKit/UIKit.h>

 

#import "AppDelegate.h"

 

int main(int argc, char *argv[])

{

    NSAutoreleasePool *pool = [[NSAutoreleasePoolallocinit];

        

    NSLog(@"正在执行main函数");

    int result = UIApplicationMain(argc, argv, nilNSStringFromClass([AppDelegateclass]));

    

    [pool drain];

    pool = nil;

    

    return result;

}
 
 
 
 
 
//=========================================================================================
 
 
 
 

//

//  AppDelegate.m

//  MacAppEntryPointFunction

//

//  Created by willonboy zhang on 12-4-10.

//  Copyright (c) 2012 willonboy.tk. All rights reserved.

//

 

#import "AppDelegate.h"

 

@implementation AppDelegate

 

@synthesize window = _window;

 

- (void)dealloc

{

    [_windowrelease];

    [superdealloc];

}

 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

    NSLog(@"正在执行didFinishLaunchingWithOptions函数");

    

    self.window = [[[UIWindowallocinitWithFrame:[[UIScreenmainScreenbounds]] autorelease];

    self.window.backgroundColor = [UIColorwhiteColor];

    [self.windowmakeKeyAndVisible];

    

    UIViewController *vc = [[UIViewControllerallocinit];

    self.window.rootViewController = vc;

    [vc release];

    

    returnYES;

}

 

@end
 
 
//=========================================================================================
 
 
 
 
 
 
 
 
 
打印出的Log如下:
 

GNU gdb 6.3.50-20050815 (Apple version gdb-1708) (Mon Aug  8 20:32:45 UTC 2011)

Copyright 2004 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "x86_64-apple-darwin".Attaching to process 4964.

2012-04-10 18:29:26.930 MacAppEntryPointFunction[4964:f803] 我比main函数还要先执行

2012-04-10 18:29:26.933 MacAppEntryPointFunction[4964:f803] 正在执行main函数

2012-04-10 18:29:27.035 MacAppEntryPointFunction[4964:f803] 正在执行didFinishLaunchingWithOptions函数
 
 
示例源码:
 
 
 

在XCode4.2中新建工程时去除了勾选ARC, 但是main.m及AppDelegate.h/m中却依然看到ARC的影子:

 

//main.m

 

int main(int argc, char *argv[])

{

    @autoreleasepool {

        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

    }

}

 

 

 

//

//  AppDelegate.h

//  ExtraUITableViewCell

//

//  Created by willonboy zhang on 12-4-9.

//  Copyright (c) 2012 willonboy.tk. All rights reserved.

//

 

#import <UIKit/UIKit.h>

 

@interface AppDelegate : UIResponder <UIApplicationDelegate>

 

@property (strong, nonatomic) UIWindow *window;

 

@end

 

 

 

原因是因为即使你不勾选ARC, 即使你在Build Settings里将ARC配置值设置为NO, 但是如果你Compliler for C/C++/Objective-C 配置值还是Apple LLVM complier 3.0,  那么ARC就还会起作用! 奇怪的事MRC(手动内存管理)也起作用! 

如下代码证明了当Compliler for C/C++/Objective-C 配置值是Apple LLVM complier 3.0, ARC配置值设置为NO时, ARC还起作用!

 

 

    NSString *tempStr = nil;

    @autoreleasepool 

    {

        tempStr = [NSString stringWithFormat:@"ARC WORK"];

        NSLog(@"%@",tempStr); //将打印出ARC WORK

    }

    NSLog(@"%@",tempStr); //将打印出空

 

 

 

 

 

 

如果你将Compliler for C/C++/Objective-C 配置值设置为LLVM GCC 4.2 上面的代码就会编译出错了, 建议不要让ARC与MRC同时有效! 

 

如果你想使用ARC, 建议看下面这两篇文章:

http://marshal.easymorse.com/archives/4626

http://marshal.easymorse.com/archives/4649

 

 

 

Tagged with:  

五项Web新兴技术

On 2012/03/28, in Web前台, by willonboy

 

web发展势头很强劲, JS也可以访问本地文件了, 不知是好事还是坏事, 很期待getUserMeida

 

最近一位 HTML5 专家 Rich Clark(作者的好朋友)为大家做了一个 HTML5 APIs 的简介,在文章中为大家指向了一个令人迷惑的网页(web 平台:浏览器技术 http://platform.html5.org/),其中包含两个很长的专栏和小正文并提及到一些让人感到迷茫的技术,例如“window.crypto.getRandomValues”和“DOM Mutation observer”。

别担心,咱们不去管那些啦,因为有些还远远没有完成呢,在浏览器中见到它们还要等一阵子。然而,其它已经在浏览器中,或者距离您很近,或者马上就要出现。人们可能将称之为“HTML5”,尽管它们并不是。其实,它们都属于令人激动的新兴 Web 技术(New Exciting Web Technology),值得每个开发者关注。

WebGL

WebGL 是一种基于 Web 的 Graphic 库,由非盈利组织 Khronos 运营,目前结合 HTML5<canvas>元素广泛应用在 3D 图形开发中。

学习 WebGL 比较困难,因为它是底层开发——它运行在 GPU 上面,而且它实际上是一个 OpenGL 的 JavaScript port,是一种游戏开发者使用的已经长期建立的 API 集。WebGL 的主要受众是哪些已经拥有丰富 OpenGL 经验的游戏开发者,他们可以通过 WebGL 为 web 平台编写游戏。

好在有很多资源可以帮助您学习 WebGL,这些资源不仅仅是关于游戏开发的,还有很多奇幻的图形、视觉和音乐视频等方面。作者个人比较推荐的是:

◆ Introduction to WebGL。http://dev.opera.com/articles/view/an-introduction-to-webgl/作者 Luz Caballero,简介可以获得的各种库。

◆ Raw WebGL 101。http://dev.opera.com/articles/view/raw-webgl-part1-getting-started/适合那些不使用库的用户。

◆ Learning WebGL。http://learningwebgl.com/一个非常好的引导网站。

◆ WebGL 101。http://www.youtube.com/watch?v=me3BviH3nZc 一个由 Erik Moller 制作的介绍视频(2.5小时)。

◆ See Emberwind。http://operasoftware.github.com/Emberwind/一个由 Erik Moller 做的 WebGL 游戏 port,您可以深入 Github 或看代码。

WebGL 目前在所有桌面浏览器(发布版和开发频道)中都支持,除了 IE10(微软表示不支持)。对于移动产品来说,已经在 Opera Mobile 12 中发布了,最终会出现在 Android,BlackBerry Playbook 2.0,Nokia N900,SonyEricsson Xpertia Android Phones 等以及 Firefox 移动浏览器中。

SVG

SVG(Scalable Vector Graphics)已经在 Opera,Firefox,Chrome 中存在多年了,但是直到 IE9 开始支持它之后才渐渐变得主流一些它在 HTML5<Canvas>的光环下显得有点暗淡,尽管 SVG 和 HTML5<canvas>是面向不用应用的不同工具。

Canvas2D 可以迅速 paint 图形到屏幕上面,这一点很犀利。但是其全部功能就是 paint 了,没有内存来做那些(位置,顶层或其他)其他功能。如果您需要那种 book-keeping 工作,就只能自己用 JavaScript 实现,因为 Canvas2D 不会把 DOM 保存到内存中,也正因为如此 Canvas2D 速度快,十分适合第一人称射击类应用。

与 Canvas2D 不同,SVG 在您需要保存 DOM 的时候就给力了。使用 JavaScript,所有的 Objects 都可以移动并且与动画无关。您可以试试 Daniel Davis 做的复古类 SVG 游戏 Inbox Attack(http://people.opera.com/danield/svg/inbox-attack.svg)来体验一下,并且看看源代码来了解如何完成动画效果。

 

因为 shape 和 path 是用 Markup 来描述的,所以他们可以用 CSS 来定型。与<canvas>不同,text 在 SVG 中保持 text 格式并且更加的灵活,更加可扩展,更加易于访问。在 Canvas 中,text 变成了像素,就像 Photoshop 中的图形 text。

SVG 最强大的特性是它基于矢量,这样您的插图,图形和 UI 图标等都是矢量图了,这样无论是在 50 英寸的电视屏还是手机屏幕桌面上,看上去感觉都是一样的清晰。在当今这样一个 web 应用无处不在的时代,SVG 图形甚至可以包括媒体查询(http://my.opera.com/ODIN/blog/2009/10/12/how-media-queries-allow-you-to-optimize-svg-icons-for-several-sizes),可以是响应式的,可以根据不同的目标设备做尺寸的调整。

综上所述,在最新的桌面浏览器中 SVG 已经能被广泛支持了。在移动产品方面的支持总体上来说也很好,以及预期在 Android 3.0 版本之前原生浏览器也会支持它了。

Daniel Davis 有一些 SVG 介绍性的资源(http://my.opera.com/tagawa/blog/learning-svg),作者个人也推荐一本免费的电子书:Learn SVG(http://www.learnsvg.com/book-learnsvg/),您也可以看看《SVG or Canvas?Choosing Between the Two》(http://dev.opera.com/articles/view/svg-or-canvas-choosing-between-the-two/)来了解二者的区别。

getUserMedia

不像那些被错误地称为 HTML5 的 API,getUserMeida(在下文中简写为 gUM)有个相对正当的理由:起初它是 HTML5<device>元素,之后它改名了然后离开了 W3C WebRTC 规范集合。

gUM 允许访问用户的摄像头和麦克风,本来是在 WebRTC 规范中在浏览器中进行 P2P 视频会议的,当 gUM 拥有了其他的用途,就离开了 WebRTC。

摄像头的访问最终在 Opera12 安卓版,Opera 桌面实验室和 Google Chrome Canary 里面实现了,不过 Opera 和 Chrome 都还没有实现麦克风的接入。

W3C 规范依然在用,所以 Opera 和 Webkit 有不同的语法规范,这样的麻烦被一个叫做 The gUM Shield(https://gist.github.com/f2ac64ed7fc467ccdfe3)的小 JavaScript 片段搞定了。如果您想更深入地了解这方面请看作者的另一篇文章:It’s Curtains for Marital Strife Thanks to getUserMedia(http://html5doctor.com/getusermedia/)

当视频从设备开始流传输的时候,源数据可以被做成变成了<video>元素,如果需要的话还可以被定为到屏幕外面,然后拷贝到<canvas>里面进行所需要的操作。Paul Neave 写的《HTML5 变成玩具!》(http://neave.com/webcam/html5/)为了方便操作把流媒体数据拷贝到 WebGL 中。作者在 .net 杂志的 226 话有采访他的报导(http://www.netmagazine.com/shop/magazines/april-2012-226)。

 

如果想把 web app 的功能做得像 native app,gUM 需要做很多的工作。试了一下 Neaver 的 gum 和 WebGL 在 Opera Mobile 12 上面的 demo,感觉和平台独有的 app 一样富有响应式并且很时髦。当在浏览器产品中其功能被广泛应用的时候,作者语言会有很多基于 web 的 QR 代码阅读者以及很多增强现实的应用。

File APIs

W3C File APIs 允许 JavaScript 访问本地文件,其中最常用的 API 是 FileReader,可以从 Opera,FireFox,IE10平台等的预览版看到(不包括 Safari)。

这一份 W3C 规范“为了在 web 应用中提供 API 来代表文件对象,以及编程选择和访问数据”。例如:你可以上传文件到浏览器中,并本地查找相关信息(例如文件名,尺寸,类型)而不需要到服务器端。您也可以打开文件,操作内容,这样可以加强基于浏览器的应用的交互性,用起来更像是本地应用。

另一个常用的用途是使传统的图像上传兑换狂更具有 Web2.0 特色:通过允许在浏览器内部的 Drag and Drop,而不是本地文件系统中改变。

您可以通过使用一个普通的<input type=”file”>开始,然后循序渐进地提高。HTML5 Drag&Drop 支持特征检测,如果存在的话就使用<div>替换<input>,那就是您的 drag 图像目标了。当图像被 drag 到目标的时候,使用 File Reader API 来显示一个指甲盖大小的图像。您可以看一下 Remy Sharp 的 demo(http://html5demos.com/file-api)。

还有很多写文件和操作文件系统的规范,不过这些对目前的跨浏览器应用来说还不太够:

W3C 文件 API:(http://dev.opera.com/articles/view/the-w3c-file-api/)非常基础的介绍。

开发文件系统 API:(http://www.html5rocks.com/en/tutorials/file/filesystem/)HTML5 Rocks 文章,(仅限 Chrome)。

Feature-detecting, progressive enhancement and upgrade messages(特征检测,渐进式增强和消息通知)

诚然,在没有那些奇幻的 API 的时候,大家总是试图使用渐进式增强和 HTML 语义的方法让网站照常工作。然而有时候却不能这样,例如 Paul Neaver 的《HTML5变成玩具》中,如果 gUM 和 WebGL 现在不存在的话,其网站不能有什么补救措施了,整个网站的核心都没了。

在这样的情况下有两种典型的惯例:要么是显示一条消息说“你的浏览器太垃圾了,塞油哪啦”或者说“你必须用 Chrome6/Firefox 4/Opera10等[插入能支持你应用的浏览器]才能访问”。第一种方法又没用又粗鲁,没有建议和补救措施;第二种方法是个临时办法,因为六个月之内所有浏览器可能都能支持你现在使用的技术了,让你在网站上留下的信息过时:例如您写的解决方案是建议使用 Firefox4 来访问,可是半年后用户安装着 Firefox7 回来访问你的页面了,这可就真的没救了。

如果您真的不能使用渐进式增强,那么就用新型的 HTML 5 Please API 吧(http://api.html5please.com/)。这是 Jon Neal,Divya Manian 和其他几位大虾创作的。通过使用它,可以先查询 caniuse.com 然后返回一个最新(能支持你的新特性的)的浏览器版本列表。

如果您已经做了一个需要 Canvas 或 WebSQL DB 技术的 DEMO 或者网站,恐怕你已经处在一个这样的尴尬境地了:您只是在告诉访问者们他们的浏览器不咋地。但是您不能只推荐他们使用一个能支持这些特性的浏览器来补救,例如“找个支持 WebRTC 性能的浏览器再来吧”,这样对于大家都没啥效果。

HTML5 Please API 把开发人员的语言(和特性)翻译成用户能理解的语言(浏览器)。通过调用这个 API 你就可以得到一些 HTML 返回值来告诉访问者,或者返回一个带有相关数据的 JSON 对象(包括浏览器 Logo 及下载介绍等信息)。这样您可以根据不同的客户来显示不同的补救信息了。

使用这种方式最令人欣慰的是:如果所有新特性在客户当前浏览器的升级版都能支持的情况下,Please API 值建议访客对浏览器升级,而不是让访客单纯为了访问你这个页面而更换浏览器。效果图如下:

 

结束语:

正如您所看到的,大量的令人惊喜的新技术正在接踵而至,您着手研究上述某项技术的时候恐怕又要担心更新鲜的技术到来了吧。希望您开发得愉快,请记得让您所开发的应用在尽可能多的浏览器上面测试一下。

———————————————————————————————

原文作者:Bruce Lawson 2012年 3 月 19 日

图片整理:Rob Winter ;HTML5阐述: Mike Brennan

原文地址:http://www.netmagazine.com/features/developers-guide-new-exciting-web-technologies

关于 Bruce Lawson :支持 Opera 开放标准,专注于 HTML5,窗口小部件和接入性。他是一位 HTML5 专家,与 Remy Sharp 共同编写了《Introducing HTML5》。他的个人网站:http://brucelawson.co.uk/

译文出自:http://www.webapptrend.com/2012/03/2234.html