IOS开发问题索引(二)

全系列文章索引:

IOS开发问题索引(一)

IOS开发问题索引(二)

IOS开发问题索引(三)

IOS开发问题索引(四)

IOS开发问题索引(五)

IOS开发问题索引(六)

IOS开发问题索引(七)

IOS开发问题索引(八)

IOS开发问题索引(九)


1、ios音频队列服务编程指南

音频队列服务编程指南

音频队列服务编程指南(AudioQueue Services Programming Guide)(一)

http://blog.csdn.net/just_we_0727/article/details/8200853

音频队列服务编程指南(AudioQueue Services Programming Guide)(二)

http://blog.csdn.net/just_we_0727/article/details/8201023

音频队列服务编程指南(AudioQueue Services Programming Guide)(三)

http://blog.csdn.net/just_we_0727/article/details/8373440

2、ios数据绑定

关于PickerView数据源的问题

http://blog.sina.com.cn/s/blog_69ee96d70100kz8r.html

PickerView的工作方式是怎样的

http://www.cocoachina.com/bbs/simple/?t22239.html

PickerView数据源的绑定在“无形”之中,因为并不是采用一种可视的方法,比如xxxx.dataSource=myDataSource,而是通过实现协议的方式,对于UIPickerVIew,需要实现如下等若干协议

3、交叉编译libogg& libvorbis   

交叉编译libogg& libvorbis

http://blog.163.com/dong_xiao_yang/blog/static/21613820520132125548615/

Tutorial: Open Source on iOS (Part 2): Compiling libogg oniOS

http://iosdeveloperzone.com/2012/09/29/tutorial-open-source-on-ios-part-2-compiling-libogg-on-ios/

Cross Compiling libogg for iOS

http://stackoverflow.com/questions/11711100/cross-compiling-libogg-for-ios

4、ios传感器总结(1)

ios传感器总结(1)

http://blog.csdn.net/shaobojohn/article/details/7843104

5、ios UIView事件注册   

UIView事件注册 

http://menglinger-520.blog.163.com/blog/static/16929433020117584733320/

6、ios进度条的实现

进度条的实现(MBProgressHUD)

http://blog.csdn.net/weasleyqi/article/details/8072897

7、ios录音功能的实现

ios录音功能的实现

http://blog.csdn.net/rs_network/article/details/6988447

iOS录音Wav音频 转换Amr,Android播放

http://blog.csdn.net/justinjing0612/article/details/9633121

http://code4app.com/ios/Sound-Recorder/4f9252d606f6e71769000000

8、Xcode引用文件注意

Xcode引用文件时,不要直接拷贝文件到项目目录,再以添加引用的形式引用,这时有可能报“找不到文件”错误,而且引用的文件目录是蓝色的,最好是直接饮用,选择copyitem的方式

9、ios 'libxml/xmlversion.h' file not found inxcode 4.2?

'libxml/xmlversion.h' file not found in xcode 4.2?

http://stackoverflow.com/questions/8850724/libxml-xmlversion-h-file-not-found-in-xcode-4-2

Remember to add the library in Link Binary en Build

Phases Section of the target project.   

IOS开发问题索引(二)_第1张图片
IOS开发问题索引(二)_第2张图片

You need to put all the libxml headers on the include

path. For Xcode do this by adding /usr/include/libxml2to theheader paths (that will pass -I/usr/include/libxml2 to the c compiler)

This is in thebuild settings tab in Search Paths -> Header Search Paths

IOS开发问题索引(二)_第3张图片


10、iosASIHTTPRequest类库简介和使用说明

ASIHTTPRequest类库简介和使用说明

http://www.cnblogs.com/dotey/archive/2011/05/10/2041966.html

ASIHTTPRequest类库在iOS 7.0中需要修改的地方

http://blog.s135.com/post/490/

代码技巧之ASIHttpRequest类库的使用

http://bbs.9ria.com/thread-259725-1-1.html

11、ios相对路径与绝对路径的转化NSBundle

ios相对路径与绝对路径的转化NSBundle

http://blog.csdn.net/zi2xuan/article/details/7319210

iOS的相对路径和绝对路径

http://wiki.eoe.cn/page/iOS_blog_page_98641.html

12、NSString字符串相加连接

NSString字符串相加连接的三种方法

http://blog.sina.com.cn/s/blog_56e2f4250102dusl.html

Objective-C语法之NSString字符串的那些事儿(三)

http://blog.csdn.net/xys289187120/article/details/6777283

13、iosXCode clang failed with exit code 254

原因:

       进入IOS虚拟机,然后直接打开了共享目录中的Xcode工程进行编译;

XCode clang failed with exit code 254

http://stackoverflow.com/questions/17426810/xcode-clang-failed-with-exit-code-254

clang failed with exit code 254 only for iOS device target

http://stackoverflow.com/questions/11984074/clang-failed-with-exit-code-254-only-for-ios-device-target

iOS 5 - Apple LLVM compiler 3.0 error

http://www.cnblogs.com/mfryf/archive/2012/02/26/2369190.html

14、正则表达式

匹配几个字符串之一:

Var tagnameRex = /(div|font|table|ol|ul)/I;             查找任何指定字符串

【整理】关于用正则表达式处理html代码方面的建议

http://www.crifan.com/for_process_html_with_many_tag_recommend_use_third_lib_while_simple_html_use_regular_expression/

15、判断js对象是否拥有某属性

http://www.cnblogs.com/snandy/archive/2011/03/04/1970162.html

两种方式,但稍有区别

1in 运算符

var obj = {name:'jack'};

alert('name' in obj);

  // --> true

alert('toString' in obj);

  // --> true

可看到无论是name,还是原形链上的toString,都能检测到返回true。

2hasOwnProperty 方法

var obj  = {name:'jack'};

obj.hasOwnProperty('name');

  // --> true

obj.hasOwnProperty('toString');

  // --> false

原型链上继承过来的属性无法通过hasOwnProperty检测到,返回false。

需注意的是,虽然in能检测到原型链的属性,但for in通常却不行。

当然重写原型后for in在IE9/Firefox/Safari/Chrome/Opera下是可见的。见:for in的缺陷

16、objective-c与js交互

 Objective-C 取得与设定 JavaScript 对象

要从 Objective-C取得网页中的 JavaScript 对象,也就是对windowScriptObject 做一些 KVC 调用,像是 valueForKey: 与 valueForKeyPath:。如果我们在 JS 里头,想要知道目前的网页位置,会这么写:

  var location = window.location.href;

用 Objective-C 就可以这么调用:

  NSString *location = [[webViewwindowScriptObject] valueForKeyPath:@"location.href"];

如果我们要设定 window.location.href,要求开启另外一个网页,在 JS 里头:

  window.location.href= 'http://spring-studio.net';

在Objective-C:

  [[webViewwindowScriptObject]setValue:@"http://spring-studio.net"forKeyPath:@"location.href"];

        由于Objective-C 与 JS 本身的语言特性不同,在两种语言之间相互传递东西之间,就可以看到两者的差别:

1、JS 虽然是 OO,但是并没有 class,所以将 JS 对象传到 Obj C 程序里头,除了基本字串会转换成 NSString、基本数字会转成 NSNumber,像是 Array 等其他对象,在 Objective-C 中,都是 WebScriptObject 这个 Class。意思就是,JS 的 Array 不会帮你转换成 NSArray。

2、从 JS 里头传一个空对象给 Objective-C 程序,用的不是 Objective-C 里头原本表示「没有东西」的方式,像是 NULL、nil、NSNull 等,而是专属 WebKit 使用的 WebUndefined。

        所以,如果我们想要看一个 JS Array 里头有什麽东西,就要先取得这个对象里头叫做 length 的 value,然后用 webScriptValueAtIndex: 去看在该 index 位置的内容。

假如我们在 JS 里头这样写:

var JSArray = {'zonble', 'dot', 'net'};

for (var i = 0; i < JSArray.length; i++) {

  console.log(JSArray[i]);

}

在Objective-C 里头就会变成这样:

WebScriptObject *obj = (WebScriptObject *)JSArray;

NSUInteger count = [[obj valueForKey:@"length"]integerValue];

NSMutableArray *a = [NSMutableArray array];

for (NSUInteger i = 0; i < count; i++) {

NSString *item = [objwebScriptValueAtIndex:i];

NSLog(@"item:%@", item);

}

 Objective-C 调用 JavaScript function

        要用 Objective-C 调用网页中的 JS function,大概有几种方法。第一种是直接写一段跟你在网页中会撰写的 JS 一模一样的程序,叫 windowScriptObject 用 evaluateWebScript: 执行。

        例如,我们想要在网页中产生一个新的 JS function,内容是:

function x(x) {

return x + 1;

}

        所以在 Objective-C 中可以这样写;

[[webView windowScriptObject] evaluateWebScript:@"function x(x) {return x + 1;}"];

        接下来我们就可以调用 window.x():

NSNumber *result = [[webView windowScriptObject]evaluateWebScript:@"x(1)"];

NSLog(@"result:%d", [result integerValue]); // Returns 2

        由于在 JS 中,每个 funciton 其实都是对象,所以我们还可以直接取得 window.x 叫这个对象执行自己。

        在 JS 里头如果这样写:

window.x.call(window.x, 1);

        Objective-C 中便是这样:

WebScriptObject *x = [[webView windowScriptObject]valueForKey:@"x"];

NSNumber *result = [xcallWebScriptMethod:@"call"withArguments:[NSArray arrayWithObjects:x,[NSNumbernumberWithInt:1], nil]];

        这种让某个 WebScriptObject 自己执行自己的写法,其实比较不会用于从 Objective-C 调用 JS 这一端,而是接下来会提到的,由 JS 调用 Objective-C,因为这样 JS 就可以把一个 callback function 送到 Objective-C 程序里头。

        如果我们在做网页,我们只想要更新网页中的一个区块,就会利用 AJAX 的技巧,只对这个区块需要的资料,对 server 发出 request,并且在 request 完成的时候,要求执行一段 callback function,更新这一个区块的显示内容。从 JS 调用 Objective-C也可以做类似的事情,如果 Objective-C程序里头需要一定时间的运算,或是我们可能是在 Objective-C 里头抓取网路资料,我们便可以把一个 callback function 送到 Objective-C程序里,要求Objective-C程序在做完工作后,执行这段 callback function。

 DOM

        WebKit 里头,所有的 DOM 对象都继承自 DOMObject,DOMObject 又继承自 WebScriptObject,所以我们在取得了某个 DOM 对象之后,也可以从 Objective-C 程序中,要求这个 DOM 对象执行 JS 程序。

        假如我们的网页中,有一个 id 叫做 “#s” 的文字输入框(text input),而我们希望现在键盘输入的焦点放在这个输入框上,在 JS 里头会这样写:

document.querySelector('#s').focus();

在Objective-C中写法:

DOMDocument *document = [[webView mainFrame] DOMDocument];

[[document querySelector:@"#s"]callWebScriptMethod:@"focus"withArguments:nil];

 JavaScript 存取 Objective-C  Value

        要让网页中的 JS 程序可以调用 Objective-C 对象,方法是把某个Objective-C 对象注册成 JS 中 window 对象的属性。之后,JS 便也可以调用这个对象的 method,也可以取得这个对象的各种 Value,只要是 KVC 可以取得的 Value,像是 NSString、NSNumber、NSDate、NSArray、NSDictionary、NSValue…等。JS 传 Array 到 Objective-C 时,还需要特别做些处理才能变成 NSArray,从 Obj C 传一个 NSArray 到 JS 时,会自动变成 JS Array。

        首先我们要注意的是将 Objective-C 对象注册给 window 对象的时机,由于每次重新载入网页,window 对象的内容都会有所变动-毕竟每个网页都会有不同的 JS 程序,所以,我们需要在适当的时机做这件事情。我们首先要指定 WebView 的 frame loading delegate(用setFrameLoadDelegate:),并且实作webView:didClearWindowObject:forFrame:,WebView 只要更新了 windowScriptObject,就会调用这一段程序。

        假如我们现在要让网页中的 JS 可以使用目前的 controller 对象,会这样写:

- (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject*)windowObject forFrame:(WebFrame *)frame

{

        [windowObjectsetValue:self forKey:@"controller"];

}

如此一来,只要调用 window.controller,就可以调用我们的 Objective-C 对象。假如我们的Objective-C Class 里头有这些成员变数:

@interface MyController : NSObject

{

    IBOutlet WebView *webView;

    IBOUtlet  NSWindow *window;

    NSString *stringValue;

    NSInteger numberValue;

    NSArray *arrayValue;

    NSDate *dateValue;

    NSDictionary *dictValue;

    NSRect frameValue;

}

@end

指定一下 Value:

stringValue = @"string";

numberValue = 24;

arrayValue = [[NSArray arrayWithObjects:@"text",[NSNumbernumberWithInt:30], nil] retain];

dateValue = [[NSDate date] retain];

dictValue =[[NSDictionary dictionaryWithObjectsAndKeys:@"value1",@"key1", @"value2", @"key2", @"value3", @"key3", nil]retain];

frameValue = [window frame];


用 JS 读读看:

var c = window.controller;

var main = document.getElementByIdx_x('main');

var HTML = '';

if (c) {

    HTML += '' +c.stringValue + '';

    HTML += '' +c.numberValue + '';

    HTML += '' +c.arrayValue + '';

    HTML += '' +c.dateValue + '';

    HTML += '' +c.dictValue + '';

    HTML += '' +c.frameValue + '';

    main.innerHTML = HTML;

}

结果如下:

string 24 text,30 2010-09-09 00:01:04 +0800 { key1 = value1; key2 =value2; key3 = value3; } NSRect: {{275, 72}, {570, 657}}

        不过,如果你看完上面的范例,就直接照做,应该不会直接成功出现正确的结果,而是会拿到一堆 undefined,原因是,Objective-C 对象的 Value 预设被保护起来,不会让 JS 直接存取。要让 JS 可以存取 Objective-C 对象的 Value,需要操作 +isKeyExcludedFromWebScript: 针对传入的 Key 一一处理,如果我们希望 JS 可以存取这个 key,就回传 NO:

+ (BOOL)isKeyExcludedFromWebScript:(const char *)name

{

    if (!strcmp(name, "stringValue")){

        return NO;

    }

    return YES;

}

      除了可以读取 Objective-C对象的 Value 外,也可以设定 Value,相当于在 Objective-C中使用 setValue:forKey:,如果在上面的 JS 程序中,我们想要修改 stringValue,直接调用 c.stringValue = ‘new value’ 即可。像前面提到,在这裡传给 Objective-C的 JS 对象,除了字串与数字外,class 都是 WebScriptObject,空对象是 WebUndefined。

  JavaScript 调用 Objective-C method

        Objective-C 的语法沿袭自 SmallTalk,Objective-C 的 selector,与 JS 的 function 语法有相当的差异。WebKit 预设的实事是,如果我们要在 JS 调用 Objective-C selector,就是把所有的参数往后面摆,并且把所有的冒号改成底线,而原来 selector 如果有底线的话,又要另外处理。

        假使我们的 controller 对象有个 method,在Objective-C 中写成这样:

- (void)setA:(id)a b:(id)b c:(id)c;

        在 JS 中就这么调用:

controller.setA_b_c_('a', 'b', 'c');

        实在有点丑。所以 WebKit 提供一个方法,可以让我们把某个 Objective-C selector 变成好看一点的 JS function。我们要实作webScriptNameForSelector:

+ (NSString *)webScriptNameForSelector:(SEL)selector

{

    if (selector == @selector(setA:b:c:)) {

        return @"setABC";

    }

    return nil;

}

        以后就可以这么调用:

controller.setABC('a', 'b', 'c');

        我们同样可以决定哪些 selector 可以给 JS 使用,哪些要保护起来,方法是实作 isSelectorExcludedFromWebScript:。而我们可以改变某个 Objective-C selector 在 JS 中的名称,我们也可以改变某个 value 的 key,方法是实作 webScriptNameForKey:。

有几件事情需要注意一下:

用 JavaScript 调用 Objective C 2.0 的property

        在上面,我们用 JS 调用 window.controller.stringValue,与设定里头的 value 时,这边很像我们使用 Objective-C 2.0 的语法,但其实做的是不一样的事情。用 JS 调用 controller.stringValue,对应到的Objective-C 语法是 [controller valueForKey:@"stringValue"],而不是调用Objective-C 对象的 property。

        如果我们的 Objective-C 对象有个 property 叫做 stringValue,我们知道,Objective-C property 其实会在编译时,变成 getter/setter method,在 JS 里头,我们便应该要调用 controller.stringValue() 与controller.setStringValue_()。

Javascript 中,Function 即对象的特性

        JS 的 function 是对象,当一个 Objective-C 对象的 method 出现在 JS 中时,这个 method 在 JS 中,也可以或多或少当做对象处理。我们在上面产生了 setABC,也可以试试看把它倒出来瞧瞧:

console.log(controller.setABC);

        我们可以从结果看到:

function setABC() { [native code] }

        这个 function 是 native code。因为是 native code,所以我们无法对这个 function 调用 call 或是 apply。

        另外,在把我们的 Objective-C 对象注册成 window.controller 后,我们会许也会想要让 controller 变成一个 function 来执行,像是调用 window.controller();或是,我们就只想要产生一个可以让 JS 调用的 function,而不是整个对象都放进 JS 里头。我们只要在 Objective-C 对象中,实作 invokeDefaultMethodWithArguments:,就可以回传在调用 window.controller() 时想要的结果。

        现在我们可以综合练习一下。前面提到,由于我们可以把 JS 对象以 WebScriptObject 这个 class 传入 Obj C 程序,Objective-C 程序中也可以要求执行 WebScriptObject 的各项 function。我们假如想把 A 与 B 两个数字丢进 Objective-C 程序里头做个加法,加完之后出现在网页上,于是我们写了一个 Objective-C method:

- (void)numberWithA:(id)a plusB:(id)b callback:(id)callback

{

    NSInteger result = [a integerValue] + [bintegerValue];

    [callbackcallWebScriptMethod:@"call" withArguments:[NSArrayarrayWithObjects:callback,            [NSNumber numberWithInteger:result],nil]];

}

JS 里头就可以这样调用:

window.controller.numberWithA_plusB_callback_(1, 2,function(result) {

    var main =document.getElementByIdx_x('main');

    main.innerText = result;

});

 其他平台上 WebKit 的用法

        除了 Mac OS X,WebKit 这几年也慢慢移植到其他的作业系统与 framework 中,也或多或少都有 Native API 要求 WebView 执行 Js,以及从 JS 调用 Native API 的机制。

        跟 Mac OS X 比较起来,IOS 上 UIWebView 的公开 API 实在少上许多。想要让 UIWebView 执行一段 JS,可以透过调用 stringByEvaluatingJavaScriptFromString:,只会回传字串结果,所以能够做到的事情也就变得有限,通常大概就拿来取得像 window.title 这些资讯。在 IOS 上我们没办法将某个 Objective-C 对象变成 JS 对象,所以,在网页中触发了某些事件,想要通知 Objective-C 这一端,往往会选择使用像「zonble://」这类 Customized URL scheme。

        ChromeOS 完全以 WebKit 製作使用者介面,不过我们没办法在 ChomeOS 上写我们在这边所讨论的桌面或行动应用程序,所以不在我们讨论之列。(顺道岔题,ChromeOS 是设计来给 Netbook 使用的作业系统,可是像 Toshiba 都已经用 Android,做出比 Netbook 更小的 Smartbook,而且应用程序更多,ChromeOS 的产品做出来的话,实在很像 Google 拿出两套东西,自己跟自己对打)。

        Android 的 WebView 对象提供一个叫做 addJavascriptInterface() 的 method,可以将某个 Java 对象注册成 JS 的 window 对象的某个属性,就可以让 JS 调用 Java 对象。不过,在调用 Java 对象时,只能够传递简单的文字、数字,複杂的 JS 对象就没办法了。而在 Android 上想要 WebView 执行一段 JS,在文件中没看到相关资料,网路上面找到的说法是,可以透过 loadUrl(),把某段 JS 用 bookmarklet 的形式传进去。

        在 QtWebKit 里头,可以对 QWebFrame 调用addToJavaScriptWindowObject,把某个 QObject 暴露在 JS 环境中,我不清楚 JS 可以传递哪些东西到 QObject 里头就是了。在 QtWebKit 中也可以取得网页里头的 DOM 对象(QWebElement、QWebElementCollection),我们可以对 QWebFrame 还有这些 DOM 对象调用 evaluateJavaScript,执行 Javascript。

        GTK 方面,因为是 C API,所以在应用程序与 JS 之间,就不是透过操作包装好的对象,而是调用 WebKit 里头 JavaScript Engine 的 C API。

 JavaScriptCore Framework

        我们在 Mac OS X 上面,也可以透过 C API,要求 WebView 执行 Javascript。首先要 import 。如果我们想要简单改一下 window.location.href:

JSGlobalContextRef globalContext = [[webView mainFrame] globalContext];

JSValueRef exception = NULL;

JSStringRef script =JSStringCreateWithUTF8CString("window.location.href='http://spring-studio.net'");

JSEvaluateScript(globalContext, script, NULL, NULL, 0, &exception);

JSStringRelease(script);

        如果我们想要让 WebView 里头的 JS,可以调用我们的 C Function:

- (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject*)windowObject forFrame:(WebFrame *)frame

{

    JSGlobalContextRef globalContext = [frameglobalContext];

    JSStringRef name =JSStringCreateWithUTF8CString("myFunc");

    JSObjectRef obj =JSObjectMakeFunctionWithCallback(globalContext, name,(JSObjectCallAsFunctionCallback)myFunc);

    JSObjectSetProperty (globalContext, [windowObjectJSObject], name, obj, 0, NULL);

JSStringRelease(name);

}

        那麽,只要 JS 调用 window.myFunc(),就可以取得们放在 myFunc 这个 C function 中回传的结果:

JSValueRef myFunc(JSContextRef ctx, JSObjectRef function, JSObjectRefthisObject, size_t argumentCount, const JSValueRefarguments[], JSValueRef* exception)

{

    return JSValueMakeNumber(ctx, 42);

}

若是传入参数是字符串,记得加上单引号‘’

参考链接:

iOS开发之Objective-C与JavaScript的交互

http://www.cnblogs.com/zhuqil/archive/2011/08/03/2126562.html

iOS UIWebView中javascript与Objective-C交互、获取摄像头

http://www.cnblogs.com/lwme/p/ios-call-objc-camera-from-javascript-in-uiwebview.html

IOS开发之——objective-c与javascript交互

http://blog.sina.com.cn/s/blog_50e0bce501018ydu.html

17、编写自文档化的代码

编写自文档化的代码

http://www.cnblogs.com/anderslly/archive/2009/06/21/write-self-documenting-code.html

编写自文档化的代码

http://kb.cnblogs.com/page/47707/

18、objective-c与js交互

如何在Objective-C的类里面声明私有方法.

http://hi.baidu.com/shiqyn/item/52887ff19d3df61aa729885f

Objective-C中的类本身并没有私有方法这个概念,声明在 .h 文件中的方法都是公有的。不过,要想实现私有方法的效果还是有办法的,就是用Category。

// Hello.h

#import

@interface Hello : NSObject {

   //变量声明

}

// 方法声明

@end

//


// Hello.m

#import "Hello.h"

@interface Hello () //=>此处Hello命名一致,后边跟括号

    //=>@property (某种) aType ivarName ; 可实现私有变量

    // 私有方法声明    

    - (void)test;

@end

@implementation Hello

    // 私有方法实现

    //=>@synthesize ivarName; 有私有变量的话

    - (void)test {

        // ..

    }

    // 方法实现

@end

        在上面这个例子中,test 就是 Hello 类的“私有方法”了。再次证明,Category这个东东真的很强大~。

19、iphone中的delegate委托机制

Objective-C回调机制(delegate,protocol)

http://blog.sina.com.cn/s/blog_6545eb460100pyjy.html

iphone中的delegate委托机制

http://wsqwsq000.iteye.com/blog/1121155

详解Objective-C中委托和协议

http://mobile.51cto.com/iphone-283416.htm

20、iOSdelegate使用时注意

delegate方法调用前,最好先判断是否可以回调:

if([_testDelegate respondsToSelector:@selector(onResult:)])

{

       [_testDelegateonResult:str];

}

你可能感兴趣的:(IOS开发问题索引(二))