iOS 开发百问(7)
71、怎样让UIWebView的大小符合HTML的内容?
在 iOS 5中。这非常easy。设置 webview 的托付。然后在托付中实现didFinishLoad:方法:
- (void)webViewDidFinishLoad:(UIWebView *)webView{
CGSize size=webView.scrollView.contentSize;//iOS 5+
webView.bounds=CGRectMake(0,0,size.width,size.height);
}
72、窗体中有多个Responder。怎样高速释放键盘
[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
这样。能够一次性让全部Responder 的失去焦点。
73、怎样让 UIWebView 能通过“捏合”手势进行缩放?
使用例如以下代码:
webview=[[UIWebView alloc]init];
webview.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
webview.scalesPageToFit=YES;
webview.multipleTouchEnabled=YES;
webview.userInteractionEnabled=YES;
74、Undefined symbols:_kCGImageSourceShouldCache、_CGImageSourceCreateWithData、_CGImageSourceCreateImageAtIndex
没有导入 ImageIO.framework。
75、 expectedmethod to read dictionary element not found on object of type nsdictionary
SDK 6.0 開始对字典添加了“下标”索引,即通过 dictionary[@"key"] 的方式检索字典中的对象。但在 SDK 5.0 中,这是非法的。你能够在项目中新建一个头文件 NSObject+subscripts.h 来解决问题 。内容例如以下:
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 60000
@interface NSDictionary(subscripts)
- (id)objectForKeyedSubscript:(id)key;
@end
@interface NSMutableDictionary(subscripts)
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key;
@end
@interface NSArray(subscripts)
- (id)objectAtIndexedSubscript:(NSUInteger)idx;
@end
@interface NSMutableArray(subscripts)
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
@end
#endif
76、错误:-[MKNetworkEngine freezeOperations]: message sent to deallocated instance0x1efd4750
这是一个内存管理错误。MKNetwork 框架支持 ARC,本来不应该出现内存管理问题,但因为 MKNetwork 中的一些 Bug,导致在 MKNetworkEngine 不被设置为 strong 属性时出现该问题。建议 MKNetworkEngine 对象设置为 ViewController 的 strong 属性。
77、UIImagePickerControllerSourceTypeSavedPhotosAlbum和 UIImagePickerControllerSourceTypePhotoLibrary的差别
UIImagePickerControllerSourceTypePhotoLibrary 表示整个照片库,允许用户选择全部的相冊(包含相机胶卷)。而UIImagePickerControllerSourceTypeSavedPhotosAlbum仅包含相机胶卷。
78、警告“Prototype tablecells must have resue identifiers”
Prototype cell(iOS 5 模板单元格)的 Identidfier 属性未填写。在属性模板中填写就可以。
79、怎样读取 info.plist 中的值?
下面演示样例代码读取了info.plist 中的 URL Schemes:
// The Info.plist isconsidered the mainBundle.
mainBundle = [NSBundle mainBundle];
NSArray* types=[mainBundle objectForInfoDictionaryKey:@"CFBundleURLTypes"];
NSDictionary* dictionary=[types objectAtIndex:0];
NSArray* schemes=[dictionary objectForKey:@"CFBundleURLSchemes"];
NSLog(@"%@",[schemes objectAtIndex:0]);
80、怎样让 AtionSheet 不自己主动解散?
UIActionSheet 不管点击什么按钮,终于都会自己主动解散。
最好的办法是子类化它。添加一个 noAutoDismiss 属性并覆盖 dismissWithClickedButtonIndex 方法,当此属性为 YES 时,不进行解散动作,为NO 时调用默认的 dismissWithClickedButtonIndex:
#import <UIKit/UIKit.h>
@interface MyAlertView : UIAlertView
@property(nonatomic, assign) BOOL noAutoDismiss;
@end
#import "MyAlertView.h"
@implementation MyAlertView
-(void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated {
if(self.noAutoDismiss)
return;
[super dismissWithClickedButtonIndex:buttonIndex animated:animated];
}
@end
81、在运行 RSA_public_encrypt函数时崩溃
这个问题非常奇怪。使用两台设备,一台系统为 6.1,一台系统为 6.02,相同的代码在 6.02 版本号中一切正常,在 6.1 版本号中导致程序崩溃:
unsigned char buff[2560]={0};
int buffSize = 0;
buffSize = RSA_public_encrypt ( strlen(cleartext),
(unsigned char*)cleartext, buff, rsa, padding );
问题在于这一句:
buffSize = RSA_public_encrypt ( strlen(cleartext),
(unsigned char*)cleartext, buff, rsa, padding );
6.1系统iPad为 3G 版,因为使用的 3G 网络(联通3gnet)信号不稳定,导致 rsa 公钥常常性取不到。故 rsa 參数出现 nil。
而 6.0 系统iPad为wifi 版,信号稳定,故无此问题。解决方法是检查 rsa 參数的有效性。
82、警告:UITextAlignmentCenteris deprecated in iOS 6
NSTextAlignmentCenter 已经被 UITextAlignmentCenter 所替代。相似的替代另一些。你能够使用下面宏:
#ifdef __IPHONE_6_0 // iOS6 and later
# define UITextAlignmentCenter (UITextAlignment)NSTextAlignmentCenter
# define UITextAlignmentLeft (UITextAlignment)NSTextAlignmentLeft
# define UITextAlignmentRight (UITextAlignment)NSTextAlignmentRight
# define UILineBreakModeTailTruncation (UILineBreakMode)NSLineBreakByTruncatingTail
# defineUILineBreakModeMiddleTruncation (UILineBreakMode)NSLineBreakByTruncatingMiddle
#endif
83、Xcode5 中无法设置 -fno-objc-arc
Xcode5 默认使用 ARC。同一时候隐藏了Compile Sources 中的“ Compiler Flags”列。因此你无法设置 .m 文件的 -fno-objc-arc 选项。要显示.m 文件的 Compiler Flags列,你能够使用菜单 “View->Utilities->Hide Utilities”来临时关闭右側的 Utilities 窗体,以显示 Compiler Flags 列。这样你就能够设置.m文件的 -fno-objc-arc 标志。
84、警告:‘ABAddressBookCreate'is deprecated:first deprecated in iOS 6.0
iOS6.0以后该方法被抛弃。用 ABAddressBookCreateWithOptions方法替代:
CFErrorRef* error=nil;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
85、iOS6.0 以后怎样读取手机通讯录?
iOS 6以后。AddressBook 框架发生了改变,尤其是app訪问手机通讯录须要获得用户授权。
因此。除了须要使用新的ABAddressBookCreateWithOptions 初始化方法之外。我们还须要使用 AddressBook 框架新的 ABAddressBookRequestAccessWithCompletion 方法,用以获知用户是否授权 :
+ (void)fetchContacts:(void (^)(NSArray *contacts))successfailure:(void (^)(NSError *error))failure {
#ifdef __IPHONE_6_0
if (ABAddressBookRequestAccessWithCompletion) {
CFErrorRef err;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &err);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
// ABAddressBook doesn'tgaurantee execution of this block on main thread, but we want our callbacks tobe
dispatch_async(dispatch_get_main_queue(), ^{
if (!granted) {
failure((__bridge NSError *)error);
} else {
readAddressBookContacts(addressBook, success);
}
CFRelease(addressBook);
});
});
}
#else
// on iOS < 6
ABAddressBookRef addressBook = ABAddressBookCreate();
readAddressBookContacts(addressBook, success);
CFRelease(addressBook);
}
#endif
}
这种方法有两个块參数 success 和 failure。分别用于运行用户授权訪问的两种情况:允许和不允许。
在代码调用 ABAddressBookRequestAccessWithCompletion函数时,第2个參数是一个块,该块的 granted 參数用于告知用户是否允许。假设 granted 为No(不允许),我们调用failure块。
假设 granted 为Yes(允许),我们将调用 readAddressBookContacts 函数,进一步读取联系人信息。
readAddressBookContacts 声明例如以下:
static voidreadAddressBookContacts(ABAddressBookRef addressBook, void (^completion)(NSArray *contacts)) {
// do stuff with addressBook
NSArray *contacts = (NSArray *)CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook));
completion(contacts);
}
首先从 addressBook 中获取全部联系人(结果放到一个NSArray 数组中)。然后调用 completion 块(即 fetchContacts 方法的 success 块)。
在 completion 中我们能够对数组进行迭代。
一个调用 fetchContacts 方法的样例:
+(void)getAddressBook:(void(^)(NSArray*))completion{
[self fetchContacts:^(NSArray *contacts) {
NSArray *sortedArray=[contactssortedArrayUsingComparator:^(id a, id b) {
NSString* fullName1=(NSString*)CFBridgingRelease(ABRecordCopyCompositeName((__bridge ABRecordRef)(a)));
NSString* fullName2=(NSString*)CFBridgingRelease(ABRecordCopyCompositeName((__bridge ABRecordRef)(b)));
int len = [fullName1 length] > [fullName2 length]? [fullName2 length]:[fullName1 length];
NSLocale *local = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_hans"];
return [fullName1 compare:fullName2 options:NSCaseInsensitiveSearch range:NSMakeRange(0, len) locale:local];
}];
completion(sortedArray);
} failure:^(NSError *error) {
DLog(@"%@",error);
}];
}
即在 fetchContacts 的完毕块中对联系人姓名进行中文排序。最后调用 completion 块。
在 fetchContacts 的错误块中。简单打印错误信息。
调用 getAddressBook的演示样例代码例如以下:
[AddressBookHelper getAddressBook:^(NSArray *node) {
NSLog(@"%@",NSArray);
}];
86、ARC警告:PerformSelector may cause a leak because itsselector is unknown
这个是 ARC 下特有的警告,用#pragma clang diagnostic宏简单地忽略它就可以:
#pragma clang diagnostic push
#pragma clang diagnostic ignored"-Warc-performSelector-leaks"
[targetperformSelector:sel withObject:[NSNumber numberWithBool:YES]];
#pragma clang diagnostic pop
87、'libxml/HTMLparser.h' file not found
导入 libxml2.dylib 后出现此错误,尤其是使用 ASIHTTP 框架的时候。
在 Build Settings的 Header SearchPaths 列表中添加“${SDK_DIR}/usr/include/libxml2”一项可解决此问题。
所谓 "$(SDK_ROOT)"是指编译目标所使用的 SDK 的文件夹,以 iPhone SDK 7.0 (真机)为例,是指/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk文件夹。
注意。似乎 Xcode 4.6 以后“User Header Search Paths”(或者“Always Search User Paths”)不再有效。因此在 “User HeaderSearch Paths”中配置路径往往是没用的。最好是配置在“Header SearchPaths”中。
88、错误:-[UITableViewdequeueReusableCellWithIdentifier:forIndexPath:]: unrecognized selector
这是 SDK 6 以后的方法,在 iOS 5.0 中这种方法为:
[UITableViewdequeueReusableCellWithIdentifier:]
89、@YES 语法在 iOS5 中无效,提示错误:Unexpected typename 'BOOL': expected expression
在 IOS6 中,@YES定义为:
#define YES ((BOOL)1)
但在 iOS 5 中。@YES 被少写了一个括号:
#define YES (BOOL)1
因此 @YES 在 iOS 5 中的正确写法应当为 @(YES)。为了简便,你也能够在 .pch 文件里修正这个 Bug:
#if __has_feature(objc_bool)
#undef YES
#undef NO
#define YES __objc_yes
#define NO __objc_no
#endif
浙公网安备 33010602011771号