1

我正在尝试为 IOS 6 添加 UIRefreshControl。

#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {
    UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
    refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"Pull to Refresh"];
    [refresh addTarget:self action:@selector(refreshView:)
      forControlEvents:UIControlEventValueChanged];
    self.refreshControl = refresh;
}

if (NSClassFromString(@"UIRefreshControl") != Nil) {
    UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
    refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"Pull to Refresh"];
    [refresh addTarget:self action:@selector(refreshView:)
      forControlEvents:UIControlEventValueChanged];
    self.refreshControl = refresh;
}

但得到错误

dyld: Symbol not found: _OBJC_CLASS_$_UIRefreshControl
Referenced from: /Users/office/Library/Application Support/iPhone    Simulator/4.3.2/Applications/DD532E42-77F9-471C-AA48-7F9EAE9268C6/Verizon.app/Verizon
Expected in:   /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/i PhoneSimulator4.3.sdk/System/Library/Frameworks/UIKit.framework/UIKit

我正在使用 IOS 6 SDK 并在 iPhone 4.3 模拟器上运行。

当我删除代码时

    UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
    refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"Pull to Refresh"];
    [refresh addTarget:self action:@selector(refreshView:)
      forControlEvents:UIControlEventValueChanged];
    self.refreshControl = refresh;

一切都适用于 iPhone 4.3 模拟器。有趣的代码里面

if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {  }

在 iPhone 4.3 模拟器上永远不会被调用,不知道为什么会出错。请帮忙!!

4

2 回答 2

1

没关系,代码不会被调用——当应用程序加载时,动态链接器需要解析应用程序二进制文件链接到的动态库中的所有符号。在 iOS 4.3 中,UIRefreshControl该类未实现,因此在运行此操作系统(以及任何早于 iOS 6 的操作系统)的设备上,操作系统本身(好吧,而不是其 UIKit 框架)不包含该类和与其对应的符号,因此应用程序甚至无法启动,即使它不使用仅适用于 iOS6 的代码。

您还需要知道预处理器宏是在编译时评估的,如果您的目标是 iOS 6,则有条件编译的代码会被编译,无论您运行的是哪个版本的 iOS,系统都会尝试执行该程序上。

解决方案:不使用条件编译,而是使用反射和自省来找出类在运行时是否可用:

Class UIRefreshControl_Class;
if ((UIRefreshControl_Class = objc_getClass("UIRefreshControl")) != Nil) {
    // class available
    id control = [[UIRefreshControl_class alloc] init];
    // etc.
}
于 2012-10-16T17:22:04.663 回答
1

绝对选择第二种风格,即:

if (NSClassFromString(@"UIRefreshControl") != nil) {
    ...
}

至于您遇到的错误,您应该可以通过在项目的“构建阶段”设置的“将二进制文件与库链接”部分中将 UIKit 设置为“可选”来停止该错误。

它应该将它标记为对您来说是可选的,因为它注意到您正在使用一个仅在 iOS 6 中可用的类,但由于某种原因看起来它不适用于您的情况。

于 2012-10-16T17:24:31.270 回答