具有ivars obj-c的类内存管理/结构

时间:2016-03-17 14:06:37

标签: objective-c memory-leaks instance-variables

我还不熟悉目标C,所以我只想弄清楚一些基本的内存管理技术。

班级方法:

- (NSString*) updateWindowName: (NSString*) windowName{

NSDictionary *error = nil;

NSAppleScript *appleScriptUpdateWindowName = [[NSAppleScript alloc] initWithSource:
                                   [[NSString alloc] initWithFormat:@\
                                    "tell application \"System Events\" to get the title of every window of process \
                                    \"BlackBee\" whose name contains \"%@\"", windowName]
                                   ];

//Execute and get the result of the OSAScript
NSAppleEventDescriptor *result = [appleScriptUpdateWindowName executeAndReturnError:&error];

//Convert to the result to a string
windowName = [NSString stringWithFormat:@"%@", result];

NSRange range = [windowName rangeOfString:@"x"];
NSString *removeFrontOfString = [windowName substringFromIndex:range.location];
NSRange range2 = [removeFrontOfString rangeOfString:@"\""];
NSString *removeEndOfString = [removeFrontOfString substringToIndex:range2.location];

return removeEndOfString;
}

主:

int main(int argc, const char * argv[]) {
@autoreleasepool {

    //Create instance of Window Class
    Window *windowClass = [[Window alloc]init];

    //Get title of all running windows
    NSArray *windowTitles = [windowClass getWindowNames];

    while (TRUE) {
        //Get the current window name
        [windowClass updateWindowName:windowTitles[0]];

        sleep(0.20);
    }      
    }
return 0;
}

我收到一个字符串,将要处理的字符串送去清理并返回清理后的字符串。问题是我在这样做时泄漏了内存,没有任何东西被释放,看起来每个对窗口类的调用都停留在内存中。如何释放班级使用的所有变量/任何内容?

其次我在每个方法中创建过滤器和applescript,因为我班级中的每个方法都有类似的过滤器。我最好在头文件中声明变量,还是在方法中更好地生成变量?

我知道这是非常基础/基本的,我做了一些谷歌搜索,但我很难找到正确的方法来做到这一点。

修改

似乎罪魁祸首是NSAppleScript和NSAppleScriptEventDescriptor,ARC不允许我手动释放NSAppleEventDescriptor,我尝试在自动释放池中包装我的while循环,并且我尝试将类方法放在autoreleasepool中,两者都没有效果。

1 个答案:

答案 0 :(得分:0)

要对此特定问题进行分类,请尝试在@autoreleasepool语句中添加一个while块:

while (TRUE) {
    @autoreleasepool {
        //Get the current window name
        [windowClass updateWindowName:windowTitles[0]];

        sleep(0.20);
    }
}

你没有对返回的字符串做任何事情,但仅仅因为它没有被任何东西使用/保留并不意味着它将真正被垃圾收集/释放回系统,因为你永远不会破坏在while循环中。